如何正确使用gluLookAt?

15

我不想涉及复杂的三角学来计算旋转和其他3D世界的事情,因此gluLookAt似乎是一个不错的替代方案。根据文档,我只需要放置相机位置的3个坐标,用于观察的3个坐标以及“上”方向。最后一个部分在我假定它应该与屏幕顶部所指的方向中视线成直角之前一点也不清楚。

它根本不是这样工作的。我有一些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个回答

39

(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。


非常感谢。现在它完美地运行了。我现在可以继续进行更高级的事情了。但是你是说gluLookAt很慢吗? - Matthew Mitchell
3
不是说OpenGL运行太慢,而是在进行严肃的OpenGL编程时,gluLookAt会隐藏一些你应该了解的东西。特别是你需要学习如何组合不同的坐标变换。这需要适应一段时间,刚开始可能有些令人沮丧,但最终会得到回报:许多图形技术都是基于巧妙地转换坐标系统构建的。 - Carlos Scheidegger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接