【问题标题】:Changing camera direction without affecting its location改变相机方向而不影响其位置
【发布时间】:2014-06-01 13:15:32
【问题描述】:

我正在根据鼠标移动和按下的按钮更改相机位置和方向。

为了根据方向将相机向前移动 5 个单位(例如),我使用以下代码:

float mview[16];
glGetFloatv(GL_MODELVIEW_MATRIX, mview);
translate_forward_camera += 5; //I have translate_right_camera and 
                               //translate_up_camera variables too
glLoadIdentity();
glTranslatef(0, 0, 5);
glMultMatrixf(mview);

与向两侧移动相同。

但是,我不知道如何在不改变其位置的情况下改变相机的方向。我在(0,0,0)处围绕自身旋转相机。 之前的 yx 旋转角度为:

old_x_ang, old_y_ang

新的 yx 旋转角度(我需要使用这个角度在 (0,0,0) 处旋转相机) 是:

x_ang, y_ang

如果我使用下面的代码,摄像头位置会改变:

glLoadIdentity();
glTranslatef(translate_right_camera,translate_up_camera,translate_forward_camera);
glRotatef(x_ang,1,0,0);
glRotatef(y_ang,0,1,0);

如何在不改变位置的情况下旋转相机?

【问题讨论】:

    标签: opengl camera rotation


    【解决方案1】:

    在典型情况下,一个视图矩阵可以分解为两个独立的变换:

    • 定义相机位置的翻译 T,以及
    • 定义相机方向的旋转 R

    您可能从世界空间中的对象放置中了解到,您通常首先(围绕对象的原点)旋转,然后将对象平移到世界空间中的最终位置。由于固定函数 GL 变换使用矩阵 * 列向量约定,因此您必须将操作定义为 T * R 以获得先旋转后平移的效果。

    这就是你在这里所做的。它不起作用。原因是视图矩阵不会将相机放置在世界中,而是将顶点从世界空间转换到视图空间的顶点变换的一部分 - 因此,视图矩阵是那个的 inverse .通常对于矩阵,您会得到 (A*B)^-1 = B^-1 * A^-1。

    所以这意味着在我们的例子中,T 是相机世界位置的倒数,而 R 是反向旋转,你必须应用 R * T。这也是完全有意义的,因为 T 将顶点转换为视图空间,其中原点是相机位置,然后您围绕该本地原点旋转以旋转相机而不改变其位置。因此,您所要做的就是将 glTranslate() 调用切换到转换序列的末尾。

    我通常会建议您停止使用 GL 矩阵堆栈,不仅因为它已被弃用并且在现代 GL 中不可用,而且还因为从 GL 中读取回矩阵的效率非常低。

    【讨论】:

      【解决方案2】:

      先旋转,再平移。通常你想先缩放,然后旋转,然后平移——以相反的顺序。对于 ModelViewProjection 矩阵,它通常如下所示:

      MVP = ProjectionViewMatrix * translationMatrix * rotationMatrix * scaleMatrix;
      

      【讨论】:

        猜你喜欢
        • 2021-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-23
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多