无法在OpenGL中移动摄像机

0 投票
3 回答
1049 浏览
提问于 2025-04-16 21:41

我正在尝试使用pyOpenGL,但在让相机正常工作方面遇到了一些问题。

def Draw():

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
     glMatrixMode(GL_MODELVIEW)
     glLoadIdentity()

     glRotatef(roty,1,0,0)
     glRotatef(rotx,0,1,0)
     glTranslate(0,0,eyez)

     glPushMatrix()

     glTranslate(0,0,-80)

     glBegin(GL_QUADS)
     glColor(0,1,0)
     glVertex3f(-50,-5,10)
     glVertex3f(-50,50,10)
     glVertex3f(50,50,10)
     glVertex3f(50,-5,10)

     glColor(1,0,0)
     glVertex3f(-50,-5,10)
     glVertex3f(-50,50,10)
     glVertex3f(-50,50,70)
     glVertex3f(-50,-5,70)
     glEnd()

     glPopMatrix()

     glutSwapBuffers()

这些旋转效果很好,但我无法朝着相机所面对的方向前进。当我修改代码以便能够向前移动时,场景的旋转就会出现问题。具体来说,如果我后退得足够远,场景就会以圆形的方式旋转。

3 个回答

0

虽然我最习惯用JOGL来编程,而不是其他OpenGL的绑定,但我建议你注意以下几点:

*) 你有没有在正确的函数中设置视口和视锥体?对我来说,这个函数是JOGL的GLEventListener中的reshape(int x, int y, int width, int height)方法。

=> 视口(就是OpenGL绘图用的框框)通常只需要调用glViewport(x,y,width,height),这样就能把整个画布区域都分配给你的GL绘图。

=> 视锥体(就是相机的视野)需要先切换到投影矩阵(glMatrixMode(GL_PROJECTION)),然后设置视锥体,最后再切换回GL_MODELVIEW矩阵,这样才能准备好进行绘图。我建议你在定义视锥体时调用gluPerspective(45, (float) width/height, 0.001f, 1000f)。这里的45是指45度的半角,width/height是用来给出屏幕的比例,0.001f是指离你眼睛(或屏幕)0.001f的近裁剪面,1000f是指离你眼睛1000f的远裁剪面。

*) 你有没有考虑在你的绘图函数中使用gluLookAt,正如Ray Toal建议的那样?我建议你调用gluLookAt(

0,0,1, // 相机位置在(0,0,1),这样它能看到(0,0,0)这个点

0,0,0, // 相机瞄准(0,0,0)

0,1,0) // 相机的上方向是(0,1,0)(所以,Oy是上方向... 逻辑上如此)

希望这些能对你有所帮助。

2

要向前移动,首先你得弄清楚“前方”指的是哪里。你需要得到一个三维向量,这个向量指向相机所面对的方向。实现这个的一个方法是把向量(0, 0, -1)乘以相机矩阵的旋转部分的逆矩阵。通常还有更简单的方法,但这些方法都得看你是怎么计算相机矩阵的。

一旦你得到了一个指向相机面对方向的单位向量,接下来的事情就简单了。只需要把这个向量乘以你想要移动的距离,然后加到相机当前的位置上。

需要注意的是,如果你使用了gluLookAt函数,你还需要同时调整观察点的位置。否则,你的相机会移动,但它会试图朝着一个在世界空间中不动的点看。

5

如果你在写一个应用程序,里面有个相机移动(还有旋转,我想也是这样),那么与其使用glRotateglTranslate来操作对象,不如看看gluLookAt。这个函数可以让你以相机为中心来设置场景,简单来说就是更方便。

顺便提一下,gluLookAt已经被淘汰了,虽然有些人说他们“很怀念”这个函数。如果你想避免使用这个被淘汰的工具函数,可以查看这个函数的源代码,然后自己在CPU上创建一个矩阵。

撰写回答