PyOpengl:更改 gluPerspective 变量使立方体闪烁
PyOpengl: Changing gluPerspective variables makes cube flash
在 glutReshapeFunc 函数中使用 gluPerspective 时,方形图像在调整大小时闪烁并在片刻后消失。
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
width = 500
height = 500
def cube():
glBegin(GL_QUADS)
glColor3f(0, 1, 0)
glVertex3f(10, 0, 0)
glVertex3f(10, 10, 0)
glVertex3f(10, 0, 0)
glVertex3f(0, 0, 0)
glVertex3f(10, 0, 0)
glVertex3f(10, 0, 10)
glVertex3f(0, 10, 0)
glVertex3f(10, 10, 0)
glVertex3f(0, 10, 0)
glVertex3f(0, 0, 0)
glVertex3f(0, 10, 0)
glVertex3f(0, 10, 10)
glVertex3f(0, 0, 10)
glVertex3f(0, 0, 0)
glVertex3f(0, 0, 10)
glVertex3f(10, 0, 10)
glVertex3f(0, 0, 10)
glVertex3f(0, 10, 10)
glVertex3f(10, 10, 10)
glVertex3f(10, 10, 0)
glVertex3f(10, 10, 10)
glVertex3f(10, 0, 10)
glVertex3f(10, 10, 10)
glVertex3f(0, 10, 10)
glEnd()
def showScreen():
global width, height
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
cube()
glutSwapBuffers()
def mouseTracker(mousex, mousey):
print(f"Mouse pos: {mousex}, {mousey}")
def reshapeWindow(x, y):
global width, height
width = x
height = y
print(x, y)
gluPerspective(45, (width / height), 0.0001, 1000)
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(500, 500)
wind = glutCreateWindow("OpenGL")
glutDisplayFunc(showScreen)
glutIdleFunc(showScreen)
glutMotionFunc(mouseTracker)
glutPassiveMotionFunc(mouseTracker)
glutReshapeFunc(reshapeWindow)
gluPerspective(45, (width / height), 0.0001, 1000)
glTranslatef(0, 0, -5)
while True:
glutMainLoopEvent()
glutPostRedisplay()
如果我像这样将 gluPerspective 放入 showScreen 函数中:
def showScreen():
global width, height
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
cube()
gluPerspective(45, (width / height), 0.0001, 1000)
glutSwapBuffers()
方块在没有调整大小的情况下闪烁,但片刻后消失了。如果我完全移除 gluPerspective,图像就会变成三角形。有什么方法可以在不使图像闪烁的情况下更改 gluPerspective 变量?
您必须在绘制立方体之前调用 gluPerspective
。矩阵运算不仅设置当前矩阵,而且定义一个新矩阵并将当前矩阵乘以新矩阵。因此,您必须加载 Identity matrix with glLoadIdentity
before modifying the matrix. The legacy OpenGL provides different current matrices for the model view matrix and the projection matrix. Before changing a matrix, select the matrix mode with glMatrixMode
:
在reshape
回调中更改投影矩阵:
def reshapeWindow(x, y):
global width, height
width = x
height = y
print(x, y)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, (width / height), 0.0001, 1000)
glMatrixMode(GL_MODELVIEW)
在应用程序循环之前或在应用程序循环中设置模型视图矩阵:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, -5)
gluPerspective
defines a Viewing frustum。视图的中心是 (0, 0)。因此,您需要更改顶点坐标。
我建议在绘制 3D 网格时启用 Depth Test。
基于您的代码的最小示例:
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import time
width = 500
height = 500
vertices = [(-1,-1,-1), ( 1,-1,-1), ( 1, 1,-1), (-1, 1,-1), (-1,-1, 1), ( 1,-1, 1), ( 1, 1, 1), (-1, 1, 1)]
faces = [(4,0,3,7), (1,0,4,5), (0,1,2,3), (1,5,6,2), (3,2,6,7), (5,4,7,6)]
colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1, 1)]
def cube():
glRotatef(1, 3, 1, 1)
glBegin(GL_QUADS)
for i, face in enumerate(faces):
glColor3fv(colors[i])
for vertex in face:
glVertex3fv(vertices[vertex])
glEnd()
def showScreen():
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
cube()
glutSwapBuffers()
def mouseTracker(mousex, mousey):
print(f"Mouse pos: {mousex}, {mousey}")
def reshapeWindow(x, y):
global width, height
width = x
height = y
print(x, y)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, (width / height), 0.0001, 1000)
glMatrixMode(GL_MODELVIEW)
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(500, 500)
wind = glutCreateWindow("OpenGL")
glutDisplayFunc(showScreen)
glutIdleFunc(showScreen)
glutMotionFunc(mouseTracker)
glutPassiveMotionFunc(mouseTracker)
glutReshapeFunc(reshapeWindow)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, -5)
glEnable(GL_DEPTH_TEST)
while True:
glutMainLoopEvent()
glutPostRedisplay()
time.sleep(0.01)
在 glutReshapeFunc 函数中使用 gluPerspective 时,方形图像在调整大小时闪烁并在片刻后消失。
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
width = 500
height = 500
def cube():
glBegin(GL_QUADS)
glColor3f(0, 1, 0)
glVertex3f(10, 0, 0)
glVertex3f(10, 10, 0)
glVertex3f(10, 0, 0)
glVertex3f(0, 0, 0)
glVertex3f(10, 0, 0)
glVertex3f(10, 0, 10)
glVertex3f(0, 10, 0)
glVertex3f(10, 10, 0)
glVertex3f(0, 10, 0)
glVertex3f(0, 0, 0)
glVertex3f(0, 10, 0)
glVertex3f(0, 10, 10)
glVertex3f(0, 0, 10)
glVertex3f(0, 0, 0)
glVertex3f(0, 0, 10)
glVertex3f(10, 0, 10)
glVertex3f(0, 0, 10)
glVertex3f(0, 10, 10)
glVertex3f(10, 10, 10)
glVertex3f(10, 10, 0)
glVertex3f(10, 10, 10)
glVertex3f(10, 0, 10)
glVertex3f(10, 10, 10)
glVertex3f(0, 10, 10)
glEnd()
def showScreen():
global width, height
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
cube()
glutSwapBuffers()
def mouseTracker(mousex, mousey):
print(f"Mouse pos: {mousex}, {mousey}")
def reshapeWindow(x, y):
global width, height
width = x
height = y
print(x, y)
gluPerspective(45, (width / height), 0.0001, 1000)
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(500, 500)
wind = glutCreateWindow("OpenGL")
glutDisplayFunc(showScreen)
glutIdleFunc(showScreen)
glutMotionFunc(mouseTracker)
glutPassiveMotionFunc(mouseTracker)
glutReshapeFunc(reshapeWindow)
gluPerspective(45, (width / height), 0.0001, 1000)
glTranslatef(0, 0, -5)
while True:
glutMainLoopEvent()
glutPostRedisplay()
如果我像这样将 gluPerspective 放入 showScreen 函数中:
def showScreen():
global width, height
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
cube()
gluPerspective(45, (width / height), 0.0001, 1000)
glutSwapBuffers()
方块在没有调整大小的情况下闪烁,但片刻后消失了。如果我完全移除 gluPerspective,图像就会变成三角形。有什么方法可以在不使图像闪烁的情况下更改 gluPerspective 变量?
您必须在绘制立方体之前调用 gluPerspective
。矩阵运算不仅设置当前矩阵,而且定义一个新矩阵并将当前矩阵乘以新矩阵。因此,您必须加载 Identity matrix with glLoadIdentity
before modifying the matrix. The legacy OpenGL provides different current matrices for the model view matrix and the projection matrix. Before changing a matrix, select the matrix mode with glMatrixMode
:
在reshape
回调中更改投影矩阵:
def reshapeWindow(x, y):
global width, height
width = x
height = y
print(x, y)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, (width / height), 0.0001, 1000)
glMatrixMode(GL_MODELVIEW)
在应用程序循环之前或在应用程序循环中设置模型视图矩阵:
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, -5)
gluPerspective
defines a Viewing frustum。视图的中心是 (0, 0)。因此,您需要更改顶点坐标。
我建议在绘制 3D 网格时启用 Depth Test。
基于您的代码的最小示例:
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import time
width = 500
height = 500
vertices = [(-1,-1,-1), ( 1,-1,-1), ( 1, 1,-1), (-1, 1,-1), (-1,-1, 1), ( 1,-1, 1), ( 1, 1, 1), (-1, 1, 1)]
faces = [(4,0,3,7), (1,0,4,5), (0,1,2,3), (1,5,6,2), (3,2,6,7), (5,4,7,6)]
colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 0, 1), (0, 1, 1)]
def cube():
glRotatef(1, 3, 1, 1)
glBegin(GL_QUADS)
for i, face in enumerate(faces):
glColor3fv(colors[i])
for vertex in face:
glVertex3fv(vertices[vertex])
glEnd()
def showScreen():
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
cube()
glutSwapBuffers()
def mouseTracker(mousex, mousey):
print(f"Mouse pos: {mousex}, {mousey}")
def reshapeWindow(x, y):
global width, height
width = x
height = y
print(x, y)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, (width / height), 0.0001, 1000)
glMatrixMode(GL_MODELVIEW)
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(500, 500)
wind = glutCreateWindow("OpenGL")
glutDisplayFunc(showScreen)
glutIdleFunc(showScreen)
glutMotionFunc(mouseTracker)
glutPassiveMotionFunc(mouseTracker)
glutReshapeFunc(reshapeWindow)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(0, 0, -5)
glEnable(GL_DEPTH_TEST)
while True:
glutMainLoopEvent()
glutPostRedisplay()
time.sleep(0.01)