3

我在 OpenGL 中实现了一个简单的相机系统。我在投影矩阵下设置了 gluPerspective,然后在 ModelView 矩阵上使用了 gluLookAt。在此之后,我有我的主渲染循环,它检查键盘事件,如果按下任何箭头键,则修改角速度和前进速度(我只通过 y 轴旋转并通过 z(向前)移动)。然后我使用以下代码移动视图(deltaTime 是自上一帧渲染以来的时间量,以秒为单位,以便将移动与帧速率分离):

//place our camera  
newTime = RunTime(); //get the time since app start  
deltaTime = newTime - time; //get the time since the last frame was rendered  
time = newTime;  
glRotatef(view.angularSpeed*deltaTime,0,1,0); //rotate  
glTranslatef(0,0,view.forwardSpeed*deltaTime); //move forwards  
//draw our vertices  
draw();  
//swap buffers  
Swap_Buffers();  

然后代码再次循环。我的绘图算法以 a 开头,以 aglPushMatrix()结尾glPopMatrix()

每次调用 glRotatef() 和 glTranslatef() 都会以视图方向的向前速度向前推动视图。

但是,当我运行代码时,我的对象被绘制在正确的位置,但是当我移动时,移动是通过世界原点的方向(0,0,0 - 面向 Z 轴)而不是本地方向完成的(我指向的地方)并且当我旋转时,旋转大约是(0,0,0)而不是相机的位置。

我最终得到了我的相机绕行 (0,0,0) 而不是原地旋转的奇怪效果。

我根本不会glLoadIdentity()在循环内的任何地方调用,并且我确信矩阵模式已设置GL_MODELVIEW为整个循环。

另一个奇怪的效果是,如果我glLoadIdentity()draw() 函数中调用(在 PushMatrix 和 PopMatrix 调用之间,屏幕就会变黑,无论我在哪里看,我都找不到我绘制的对象。

有谁知道我为了使这个轨道(0,0,0)而不是当场旋转而搞砸了什么?

4

3 回答 3

6

glRotate()围绕世界原点旋转模型视图矩阵,因此要围绕某个任意点旋转,您需要平移矩阵以使该点位于原点,旋转然后平移回您开始的位置。

我想你需要的是这个

float x, y, z;//point you want to rotate around

glTranslatef(0,0,view.forwardSpeed*deltaTime); //move forwards

glTranslatef(x,y,z); //translate to origin
glRotatef(view.angularSpeed*deltaTime,0,1,0); //rotate
glTranslatef(-x,-y,-z); //translate back
//draw our vertices
draw();
//swap buffers
Swap_Buffers();
于 2009-12-30T00:54:53.960 回答
1

交换你的旋转和翻译电话:)

由于它们对矩阵堆栈进行了后乘,因此如果您关心这类事情,那么最后一个被调用的是概念上应用的“第一个”。

于 2009-12-30T00:18:29.790 回答
0

我认为您首先必须将相机平移到点 (0,0,0),然后旋转,然后再将其平移回来。

于 2009-12-30T00:35:55.493 回答