OpenGL - 如何使用gluLookAt移动场景以响应鼠标输入

时间:2012-06-12 21:20:43

标签: qt opengl glulookat

我通过QGLWidget在Qt中使用OpenGL,我正在尝试实现一些基本的鼠标和键盘驱动的交互。

例如,键盘箭头键将用于“平移”场景,鼠标滚轮用于放大场景,鼠标应用于旋转模型。

我已经想出了如何实现平移和缩放,但是我在实现旋转方面遇到了麻烦。

这是我到目前为止所做的:

void MyGLWidget::paintGL() {
    glLoadIdentity();
    gluLookAt(0+camDelta[0],0+camDelta[1],-100+camDelta[2],centerCoords[0]+lookAtDelta[0],centerCoords[1]+lookAtDelta[1],centerCoords[2]+lookAtDelta[2],0,1,0);
    // draw stuff here
}

所以基本上我设置了初始的gluLookAt参数,然后添加了两个数组float camDelta[3]float lookAtDelta[3],以跟踪摄像机位置的变化以及它在响应的位置用户与场景交互。

对于鼠标滚轮,我这样做:

void MyGLWidget::wheelEvent(QWheelEvent *event) {
    camDelta[2] += (event->delta() / 8.0 / 15.0) * WHEEL_DELTA;
    lookAtDelta[2] += (event->delta() / 8.0 / 15.0) * WHEEL_DELTA;
    updateGL();
}

同样在MyGLWidget::keyPressEvent中,我会修改增量“[0]字段以向左和向右平移,以及增量”[1]用于向上和向下平移。

所以我的问题是,如何使用鼠标实现类似的支持旋转?我有点困惑,因为我猜我不仅要以某种方式改变相机的外观以及向上的向量,但我并不清楚如何做到这一点。

2 个答案:

答案 0 :(得分:3)

我为这样的事情做了什么叫做轨道相机模型。

您可以跟踪摄像机目标位置(或查看)以及其他3个参数:方位角,赤纬(或倾斜度)和距离(或半径)。方位角是相机围绕目标水平旋转(就像目标在地面上,并且在看着它的同时绕着它走动一圈)。赤纬是垂直旋转。距离是目标和相机之间的距离。

这些也称为球面坐标:

http://mathworld.wolfram.com/SphericalCoordinates.html

你想要这样的方程:

x = r * sin(phi) * cos(theta)
y = r * sin(phi) * sin(theta)
z = r * cos(phi)

其中r是距离,θ是方位角,phi是赤纬。 这为您提供了从相机外观位置到相机位置的偏移。

所以这就是你做的。保持相机目标位置,但不保持相机位置。平移相机时,移动目标位置。旋转相机时,调整方位角和偏角。缩放相机时,请调整距离。然后,在调用gluLookAt之前的每一帧,使用上面的公式计算相机位置。您只需将x,y和z添加到目标位置。

答案 1 :(得分:0)

最好的办法是使用四元数。就像复数对于在2D中旋转非常有用一样,四元数非常适合3D旋转。

标准'围绕x,y,z轴旋转'可以工作,它会表现得很奇怪而且不像预期的那样。

您可以在http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation

获得有关所有这些内容的精彩教程