OpenGL相机旋转

时间:2012-04-06 19:02:54

标签: opengl camera rotation

在OpenGL中,我正在尝试创建一个免费的飞行摄像头。我的问题是Y轴上的旋转。摄像机应始终在Y世界轴上旋转,而不是在本地方向上旋转。我尝试了几次矩阵乘法,但都没有结果。与

camMatrix = camMatrix  * yrotMatrix 

沿着本地轴旋转相机。

camMatrix = yrotMatrix * camMatrix

沿着世界轴旋转相机,但始终围绕原点旋转。但是,旋转中心应该是相机。有人有点想法吗?

4 个答案:

答案 0 :(得分:4)

3D编程的一个比较棘手的方面就是正确地进行复杂的转换。

在OpenGL中,每个点都用模型/视图矩阵转换,然后用投影矩阵转换。

模型视图矩阵获取每个点并将其从相机的视角转换到应该的位置。投影矩阵转换点的坐标,以便X和Y坐标可以轻松地映射到窗口。

要使模式/视图矩阵正确,您必须从单位矩阵(不改变顶点的矩阵)开始,然后对相机的位置和方向应用变换,然后为对象的位置和方向应用< em>按相反顺序。

您需要记住的另一件事是,旋转总是关于以原点(0,0,0)为中心的轴。因此,当你为相机应用旋转变换时,无论你是转动它(就像你转过头)或绕着原点绕轨道运行它绕地球轨道运行Sun)取决于您之前是否已应用翻译转换。

因此,如果你想旋转和环绕相机,你需要:

  1. 应用旋转以定向相机
  2. 应用翻译来定位
  3. 将旋转应用于围绕原点旋转的相机
  4. (可选)应用平移将相机移动到其设定方向,以将其移动到围绕(0,0,0)以外的点的轨道运行。
  5. 如果您想要将相机指向不是(0,0,0)的点并且还以该设定距离绕该点运行,那么事情会变得更加复杂,同时还能够俯仰或偏航相机。有关WebGL中的示例,请参阅here。寻找GLViewerBase.prototype.display

    Red Book covers transforms in much more detail

    另请注意gluLookAt,您可以使用它来将相机指向,而无需使用旋转。

答案 1 :(得分:3)

您可能会发现创建一个存储位置和正交nuv轴的相机类,并适当地旋转它们,而不是使用矩阵执行此操作。例如见:

https://github.com/sgolodetz/hesperus2/blob/master/Shipwreck/MapEditor/GUI/Camera.java

https://github.com/sgolodetz/hesperus2/blob/master/Shipwreck/MapEditor/Math/MathUtil.java

然后你写下这样的话:

if(m_keysDown[TURN_LEFT])
{
    m_camera.rotate(new Vector3d(0,0,1), deltaAngle);
}

在设置相机视图时,您可以:

gl.glLoadIdentity();
glu.gluLookAt(m_position.x, m_position.y, m_position.z,
              m_position.x + m_nVector.x, m_position.y + m_nVector.y, m_position.z + m_nVector.z,
              m_vVector.x, m_vVector.y, m_vVector.z);

如果您想知道如何围绕像(0,0,1)这样的任意轴进行旋转,请参阅上面代码中的MathUtil.rotate_about_axis

答案 2 :(得分:1)

如果您不想基于前一帧中的相机进行变换,我的建议可能就是抛弃矩阵复合并在每帧重新计算它。我不认为有一种方法可以用单个矩阵做你想要的,因为它存储了平移和旋转。

我想如果你只想要一个俯仰/偏航相机,只需将这些值存储为两个浮点数,然后根据它重建矩阵。也许像伪代码那样:

onFrameUpdate() {
  newPos = camMatrix * (0,0,speed) //move forward along the camera axis
  pitch += mouse_move_x;
  yaw += mouse_move_y;

  camMatrix = identity.translate(newPos)
  camMatrix = rotate(camMatrix, (0,1,0), yaw)
  camMatrix = rotate(camMatrix, (1,0,0), pitch)
}

答案 3 :(得分:0)

  

沿着世界轴旋转相机,但始终围绕原点旋转。但是,旋转中心应该是相机。有人有点想法吗?

我假设矩阵以这种方式存储在内存中(如果矩阵是线性1d数组,则数字表示元素索引):

0   1   2   3    //row 0
4   5   6   7    //row 1
8   9   10  11   //row 2
12  13  14  15   //row 3

<强>解决方案

  1. 将最后一行相机矩阵存储在临时变量中。
  2. 将相机矩阵的最后一行设置为(0,0,0,1)
  3. 使用camMatrix = yrotMatrix * camMatrix
  4. 从临时变量恢复相机矩阵的最后一行。