Python OpenGL - 在3d场景中显示2d图形的问题

时间:2017-03-31 01:15:06

标签: python opengl 3d 2d hud

我的目标是使用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)。下一个函数(重塑)是获取当前窗口大小,以便我可以将其输入矩阵投影的比例。以下函数(scene3d)创建立方体并将其设置在场景的中心,而(scene2d)创建三角形并将其设置在场景的左下角。 (绘制)函数将所有内容按顺序放置,其中首先渲染3d场景,然后放置2d场景[我在推动和弹出矩阵下嵌套]。最后,main函数创建窗口并启动循环。

非常感谢您的反馈。谢谢你,祝你有愉快的一天!

1 个答案:

答案 0 :(得分:1)

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(),您应该看到: