Python OpenGL - 在 3d 场景上显示 2d 图形时出现问题
Python OpenGL - Issues displaying 2d graphics over a 3d scene
我的目标是使用 PyOpenGL 在旋转的立方体上显示静态三角形。但是,我没有运气达到我想要的结果;相反,我只剩下一个空白屏幕。我已经在单独的文件上用相应的矩阵投影测试了立方体和三角形,以确保场景本身不是问题。果然,事实并非如此。
三角脚本
在屏幕左下角显示一个三角形。
def reshape(width, height):
glViewport(0, 0, width, height)
glClearColor(0.0, 0.0, 0.0, 0.0)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, 0, 0.1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
#--- func for defining triangle
def drawTriangle():
### clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
### draw triangle
glBegin(GL_TRIANGLES)
glColor3f(0.0, 1.0, 0.0)
glVertex2f(0, 0)
glVertex2f(100, 0)
glVertex2f(0, 100)
glEnd()
glutSwapBuffers()
#--- func for main loop
def main():
window = 0
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE)
glutInitWindowSize(640, 480)
glutInitWindowPosition(200, 200)
window = glutCreateWindow(b'OpenGL Python Triangle')
glutReshapeFunc(reshape)
glutDisplayFunc(drawTriangle)
glutIdleFunc(drawTriangle)
glutMainLoop()
if __name__ == '__main__':
main()
立方体脚本
在屏幕中央显示一个立方体。
def reshape(width, height):
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthMask(GL_TRUE)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(width)/float(height), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
#--- func for defining cube
def drawCube():
### clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
### set position and rotation
glLoadIdentity()
glTranslatef(0.0,0.0,-6.0)
glRotatef(30,1.0,0.0,0.0)
glRotatef(0,0.0,1.0,0.0)
glRotatef(30,0.0,0.0,1.0)
### draw cube
glBegin(GL_QUADS)
#/* Long list of vertices
glEnd()
glutSwapBuffers()
#--- func for main loop
def main():
window = 0
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(640,480)
glutInitWindowPosition(200,200)
window = glutCreateWindow(b'OpenGL Python Cube')
glutReshapeFunc(reshape)
glutDisplayFunc(drawCube)
glutIdleFunc(drawCube)
glutMainLoop()
if __name__ == "__main__":
main()
我认为深度测试可能会出现问题,但我未能提供任何证明该想法正确的结果。相反,它可能与组织矩阵投影有关。我订购它是为了先渲染 3d 场景,然后再渲染 2d 场景。
HUD 脚本
#--- 3D projection function
def render3d():
global width, height
### clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glViewport(0, 0, width, height)
### projection mode
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(width)/float(height), 0.1, 100.0)
### modelview mode
glMatrixMode(GL_MODELVIEW)
### setup 3d shader
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)
#--- 2D projection function
def render2d():
global width, height
### projection mode
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0.0, width, height, 0.0)
### modelview mode
glMatrixMode(GL_MODELVIEW)
### setup 2d shader
glDisable(GL_DEPTH_TEST)
#--- reshape function
def reshape(new_width, new_height):
global width, height
### apply new window size
width = new_width
height = new_height
#--- 3D cube function
def scene3d():
### setup polygon location & orientation
glTranslatef(0.0, 0.0, -6.0)
glRotatef(30, 1.0, 0.0, 0.0)
glRotatef(0, 1.0, 1.0, 0.0)
glRotatef(30, 0.0, 0.0, 1.0)
### draw cube
glBegin(GL_QUADS)
glColor3f(0.0,1.0,0.0)
glVertex3f( 1.0, 1.0,-1.0)
glVertex3f(-1.0, 1.0,-1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f( 1.0, 1.0, 1.0)
glColor3f(1.0,0.0,0.0)
glVertex3f( 1.0,-1.0, 1.0)
glVertex3f(-1.0,-1.0, 1.0)
glVertex3f(-1.0,-1.0,-1.0)
glVertex3f( 1.0,-1.0,-1.0)
glColor3f(0.0,1.0,1.0)
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0,-1.0, 1.0)
glVertex3f( 1.0,-1.0, 1.0)
glColor3f(1.0,1.0,0.0)
glVertex3f( 1.0,-1.0,-1.0)
glVertex3f(-1.0,-1.0,-1.0)
glVertex3f(-1.0, 1.0,-1.0)
glVertex3f( 1.0, 1.0,-1.0)
glColor3f(0.0,0.0,1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0, 1.0,-1.0)
glVertex3f(-1.0,-1.0,-1.0)
glVertex3f(-1.0,-1.0, 1.0)
glColor3f(1.0,0.0,1.0)
glVertex3f( 1.0, 1.0,-1.0)
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f( 1.0,-1.0, 1.0)
glVertex3f( 1.0,-1.0,-1.0)
glEnd()
#--- 2D triangle function
def scene2d():
### draw triangle
glBegin(GL_TRIANGLES)
glColor3f(0.0, 1.0, 0.0)
glVertex2f(0, 0)
glVertex2f(100, 0)
glVertex2f(0, 100)
glEnd()
#--- draw function
def draw():
### 3D scene
render3d()
scene3d()
### 2D scene
glPushMatrix()
render2d()
scene2d()
glPopMatrix()
### swap buffers
glutSwapBuffers()
#--- main loop function
def main():
window = 0
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(640,480)
glutInitWindowPosition(200,200)
window = glutCreateWindow(b'OpenGL Python HUD')
glutReshapeFunc(reshape)
glutDisplayFunc(draw)
glutIdleFunc(draw)
glutMainLoop()
#--- only run if this is the main module
if __name__ == "__main__":
main()
为了解释,我定义了两个矩阵投影函数:一个用于3d场景(render3d),另一个用于2d场景(render2d)。下一个函数 (reshape) 是获取当前的 window 大小,以便我可以将其输入到矩阵投影的比例中。以下函数 (scene3d) 创建立方体并将其设置在场景的中心,而 (scene2d) 创建三角形并将其设置在场景的左下角。 (draw) 函数按顺序排列所有内容,首先渲染 3d 场景,然后渲染 2d 场景 [我将其嵌套在 push 和 pop 矩阵下]。最后,主函数创建 window 并开始循环。
非常感谢您提供反馈。谢谢你,祝你有愉快的一天!
在 draw()
里面考虑一下:
def draw():
render3d()
scene3d()
glPushMatrix()
render2d()
scene2d()
glPopMatrix()
注意到有什么遗漏了吗?
另一部分也应该有一个glPushMatrix()
和glPopMatrix()
:
def draw():
glPushMatrix()
render3d()
scene3d()
glPopMatrix()
glPushMatrix()
render2d()
scene2d()
glPopMatrix()
您看到黑屏的原因是因为您在 scene3d()
内呼叫 glTranslatef()
。因此,启动应用程序后几毫秒内的所有内容都会在屏幕外翻译。
添加缺失的 glPushMatrix()
和 glPopMatrix()
,您应该会看到:
我的目标是使用 PyOpenGL 在旋转的立方体上显示静态三角形。但是,我没有运气达到我想要的结果;相反,我只剩下一个空白屏幕。我已经在单独的文件上用相应的矩阵投影测试了立方体和三角形,以确保场景本身不是问题。果然,事实并非如此。
三角脚本
在屏幕左下角显示一个三角形。
def reshape(width, height):
glViewport(0, 0, width, height)
glClearColor(0.0, 0.0, 0.0, 0.0)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, 0, 0.1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
#--- func for defining triangle
def drawTriangle():
### clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
### draw triangle
glBegin(GL_TRIANGLES)
glColor3f(0.0, 1.0, 0.0)
glVertex2f(0, 0)
glVertex2f(100, 0)
glVertex2f(0, 100)
glEnd()
glutSwapBuffers()
#--- func for main loop
def main():
window = 0
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE)
glutInitWindowSize(640, 480)
glutInitWindowPosition(200, 200)
window = glutCreateWindow(b'OpenGL Python Triangle')
glutReshapeFunc(reshape)
glutDisplayFunc(drawTriangle)
glutIdleFunc(drawTriangle)
glutMainLoop()
if __name__ == '__main__':
main()
立方体脚本
在屏幕中央显示一个立方体。
def reshape(width, height):
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthMask(GL_TRUE)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(width)/float(height), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
#--- func for defining cube
def drawCube():
### clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
### set position and rotation
glLoadIdentity()
glTranslatef(0.0,0.0,-6.0)
glRotatef(30,1.0,0.0,0.0)
glRotatef(0,0.0,1.0,0.0)
glRotatef(30,0.0,0.0,1.0)
### draw cube
glBegin(GL_QUADS)
#/* Long list of vertices
glEnd()
glutSwapBuffers()
#--- func for main loop
def main():
window = 0
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(640,480)
glutInitWindowPosition(200,200)
window = glutCreateWindow(b'OpenGL Python Cube')
glutReshapeFunc(reshape)
glutDisplayFunc(drawCube)
glutIdleFunc(drawCube)
glutMainLoop()
if __name__ == "__main__":
main()
我认为深度测试可能会出现问题,但我未能提供任何证明该想法正确的结果。相反,它可能与组织矩阵投影有关。我订购它是为了先渲染 3d 场景,然后再渲染 2d 场景。
HUD 脚本
#--- 3D projection function
def render3d():
global width, height
### clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glViewport(0, 0, width, height)
### projection mode
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(width)/float(height), 0.1, 100.0)
### modelview mode
glMatrixMode(GL_MODELVIEW)
### setup 3d shader
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)
#--- 2D projection function
def render2d():
global width, height
### projection mode
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0.0, width, height, 0.0)
### modelview mode
glMatrixMode(GL_MODELVIEW)
### setup 2d shader
glDisable(GL_DEPTH_TEST)
#--- reshape function
def reshape(new_width, new_height):
global width, height
### apply new window size
width = new_width
height = new_height
#--- 3D cube function
def scene3d():
### setup polygon location & orientation
glTranslatef(0.0, 0.0, -6.0)
glRotatef(30, 1.0, 0.0, 0.0)
glRotatef(0, 1.0, 1.0, 0.0)
glRotatef(30, 0.0, 0.0, 1.0)
### draw cube
glBegin(GL_QUADS)
glColor3f(0.0,1.0,0.0)
glVertex3f( 1.0, 1.0,-1.0)
glVertex3f(-1.0, 1.0,-1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f( 1.0, 1.0, 1.0)
glColor3f(1.0,0.0,0.0)
glVertex3f( 1.0,-1.0, 1.0)
glVertex3f(-1.0,-1.0, 1.0)
glVertex3f(-1.0,-1.0,-1.0)
glVertex3f( 1.0,-1.0,-1.0)
glColor3f(0.0,1.0,1.0)
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0,-1.0, 1.0)
glVertex3f( 1.0,-1.0, 1.0)
glColor3f(1.0,1.0,0.0)
glVertex3f( 1.0,-1.0,-1.0)
glVertex3f(-1.0,-1.0,-1.0)
glVertex3f(-1.0, 1.0,-1.0)
glVertex3f( 1.0, 1.0,-1.0)
glColor3f(0.0,0.0,1.0)
glVertex3f(-1.0, 1.0, 1.0)
glVertex3f(-1.0, 1.0,-1.0)
glVertex3f(-1.0,-1.0,-1.0)
glVertex3f(-1.0,-1.0, 1.0)
glColor3f(1.0,0.0,1.0)
glVertex3f( 1.0, 1.0,-1.0)
glVertex3f( 1.0, 1.0, 1.0)
glVertex3f( 1.0,-1.0, 1.0)
glVertex3f( 1.0,-1.0,-1.0)
glEnd()
#--- 2D triangle function
def scene2d():
### draw triangle
glBegin(GL_TRIANGLES)
glColor3f(0.0, 1.0, 0.0)
glVertex2f(0, 0)
glVertex2f(100, 0)
glVertex2f(0, 100)
glEnd()
#--- draw function
def draw():
### 3D scene
render3d()
scene3d()
### 2D scene
glPushMatrix()
render2d()
scene2d()
glPopMatrix()
### swap buffers
glutSwapBuffers()
#--- main loop function
def main():
window = 0
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(640,480)
glutInitWindowPosition(200,200)
window = glutCreateWindow(b'OpenGL Python HUD')
glutReshapeFunc(reshape)
glutDisplayFunc(draw)
glutIdleFunc(draw)
glutMainLoop()
#--- only run if this is the main module
if __name__ == "__main__":
main()
为了解释,我定义了两个矩阵投影函数:一个用于3d场景(render3d),另一个用于2d场景(render2d)。下一个函数 (reshape) 是获取当前的 window 大小,以便我可以将其输入到矩阵投影的比例中。以下函数 (scene3d) 创建立方体并将其设置在场景的中心,而 (scene2d) 创建三角形并将其设置在场景的左下角。 (draw) 函数按顺序排列所有内容,首先渲染 3d 场景,然后渲染 2d 场景 [我将其嵌套在 push 和 pop 矩阵下]。最后,主函数创建 window 并开始循环。
非常感谢您提供反馈。谢谢你,祝你有愉快的一天!
在 draw()
里面考虑一下:
def draw():
render3d()
scene3d()
glPushMatrix()
render2d()
scene2d()
glPopMatrix()
注意到有什么遗漏了吗?
另一部分也应该有一个glPushMatrix()
和glPopMatrix()
:
def draw():
glPushMatrix()
render3d()
scene3d()
glPopMatrix()
glPushMatrix()
render2d()
scene2d()
glPopMatrix()
您看到黑屏的原因是因为您在 scene3d()
内呼叫 glTranslatef()
。因此,启动应用程序后几毫秒内的所有内容都会在屏幕外翻译。
添加缺失的 glPushMatrix()
和 glPopMatrix()
,您应该会看到: