Pygame + OpenGL + 视锥体不显示任何内容

0 投票
2 回答
573 浏览
提问于 2025-04-17 06:28

我正在尝试用pygame和opengl设置一个简单的3D视图,使用视锥体来设置投影矩阵。以下是我的初始化代码:

def initgl(self):
    glClearColor(0.0,0.0,0.0,0.0)
    glViewport(0,0,640,480)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glFrustum(0,640,480,0,.1,1000.)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

这是我的显示代码:

def paintgl(self):
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    glPushMatrix()
    glColor3f(1.0,1.0,1.0)
    glBegin(GL_QUADS)
    glVertex3f(-1.0,-1.0,0.0)
    glVertex3f(1.0,-1.0,0.0)
    glVertex3f(1.0,1.0,0.0)
    glVertex3f(-1.0,1.0,0.0)
    glEnd()
    glPopMatrix()

奇怪的是,当我使用glOrtho时,一切都显示得很正常。我的问题是,我在做什么错事,让pygame无法显示这个opengl代码呢?

编辑:
如果我渲染到一个显示列表,那个显示列表工作得很好,只有在我调用它的时候才会显示,但我的几何图形仍然缺失。

注意,我确实把视场角(FOV)改得更正确了(近处是1,远处是10),而且我把我的几何图形推到Z轴的2的位置,结果还是没有显示。

解决了:
我没有朝正确的方向看。哈哈。

2 个回答

1

我从来没有用过glFrustum(顺便说一下,从OpenGL3.3开始,整个矩阵栈已经不再推荐使用了),不过看起来第五个参数是近裁剪面,所以你的几何图形就简单地在它后面了!

换句话说,所有的顶点已经在世界空间里(因为你没有设置模型视图矩阵),而且它们的Z坐标是0.0,所以它们就在0.1的近裁剪面后面。

1

initgl的代码放到paintgl里面,这样会更整洁,也能避免以后很多麻烦。

近裁剪面应该尽量设置得远一些,远裁剪面则尽量设置得近一些。你现在的近远裁剪面设置会严重影响深度缓冲区的精度。任何距离超过100单位的物体都会出现Z缓冲区冲突(除非它们的规模非常大)。


换句话说,你的几何图形实际上是在近裁剪面后面,也就是说离得太近看不见。把它稍微往-Z方向移动一下。


更新:代码建议

def paintgl(self):
    glClearColor(0.0,0.0,0.0,0.0)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

    glViewport(0,0,640,480)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glFrustum(0,640,480,0,1.,10.)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    glTranslatef(0., 0., -2.)

    glColor3f(1.0,1.0,1.0)
    glBegin(GL_QUADS)
    glVertex3f(-1.0,-1.0,0.0)
    glVertex3f(1.0,-1.0,0.0)
    glVertex3f(1.0,1.0,0.0)
    glVertex3f(-1.0,1.0,0.0)
    glEnd()

撰写回答