如何正确使用gluLookAt?
我不想为了我的3D世界去搞复杂的三角函数来计算旋转之类的,所以觉得使用gluLookAt是个不错的选择。根据文档,我只需要设置三个坐标来表示相机的位置,三个坐标来表示我应该看的地方,还有一个“向上”的位置。这个“向上”的位置我一开始没搞懂,直到我想象它应该和视线成直角,也就是屏幕顶部的方向。
但实际上并不是这样。我有一些Python代码。这段代码初始化了一些数据,还有进入这个游戏部分时的一些模式代码:
def init(self):
self.game_over = False
self.z = -30
self.x = 0
def transfer(self):
#Make OpenGL use 3D
game.engage_3d(45,0.1,100)
gluLookAt(0,0,-30,0,0,0,0,1,0)
“game.engage_3d(45,0.1,100)”基本上是设置投影矩阵,使视角为45度,近处和远处的坐标分别是0.1和100。
第一次调用gluLookAt时,相机的位置设置得很好。
我画了一个中心在(0,0,0)的立方体,使用gluLookAt之前它工作得很好。在我绘制它之前,我有这段代码:
gluLookAt(self.x,0,self.z,0,0,0,0,1,0)
if game.key(KEY_UP):
self.z += 2.0/game.get_fps()
if game.key(KEY_DOWN):
self.z -= 2.0/game.get_fps()
if game.key(KEY_LEFT):
self.x += 2.0/game.get_fps()
if game.key(KEY_RIGHT):
self.x -= 2.0/game.get_fps()
根据这段代码,向上的位置应该始终保持不变,因为它总是与视线成直角。我本以为它会让相机在z轴上前后移动(用上下键),在x轴上左右移动(用左右键)。但实际上,当我按左右键时,立方体会围绕“眼睛”旋转,旋转的速度会随着按键加快。按上键会让一个神秘的立方体从屏幕外出现并撞击第一个立方体,而按下键又把这个神秘的立方体收回去。这个旋转和出现的立方体结合在一起,产生了完全不同的效果,正如文档所说的那样。
到底出了什么问题呢?
谢谢。
1 个回答
关于gluLookAt中的“上”向量,其实很简单:想象一下你在看某个东西。现在把头倾斜90度。你的位置没有变,看的方向也没变,但你眼睛里看到的画面明显变了。那有什么不同呢?就是你头顶指向的方向。这就是上向量。
不过来回答你的问题:gluLookAt的调用不应该连在一起。换句话说,如果你不太明白它是怎么工作的,唯一可以使用gluLookAt的方式就是下面这个:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
# do not touch the modelview matrix anymore!
从你的代码来看,你似乎在做这样的事情:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
# some stuff..
gluLookAt(...);
这样会产生奇怪的结果,因为gluLookAt会把当前的矩阵和它计算出来的视图矩阵相乘。如果你想要组合变换,最好还是弄清楚怎么使用glTranslate、glScale和glRotatef。更好的是,你应该学习一下坐标变换是怎么工作的,然后使用glMultMatrix。