OpenGL 相机旋转不起作用

发布于 2024-11-08 19:36:27 字数 1812 浏览 0 评论 0原文

我知道这是一个常见问题(因为我已经阅读了这里和其他论坛上的许多帖子),但对于我的一生来说,我无法获得我想要的相机旋转。我希望相机能够“环视四周”,而不是围绕某个点“绕轨道运行”,该点是 OpenGL 原点。

我知道“OpenGL 中没有相机”,地形移动而不是视点等等以及所有这些类似的概念,但它并没有帮助我解决这个问题。

不幸的是,我很顽固,希望编写没有弃用功能的代码,因此这消除了我读过的 99% 的类似情况,因为大多数解决方案都使用 gluLook 和类似的函数。

我使用的矩阵类与 OpenGL SuperBible 第 5 版 ( source,GLFrame.h 是感兴趣的主要文件),但已对其进行调整以使用 OpenGL数学图书馆

对这个问题的典型回答是平移到原点,旋转,然后平移回来,但这对我没有任何作用。

一些代码:

void rotateLocalX( GLfloat p_Angle )
{
    if( ( m_Roll < m_RollLimit ) && ( m_Roll > ( -m_RollLimit ) ) )
    {
        //store away the current location so I can translate back to it
        glm::vec3 tempOrigin = getOrigin( );

        m_Roll += p_Angle;

        // Go to the Origin

        //you can also subtract the current location to get to 0.f

        //also doing glm::translate( m_Matrix, -( tempOrigin ) ); -> rotate -> 
        //glm::translate( m_Matrix, tempOrigin ) has the same result
        m_Matrix[ 3 ][ 0 ] = 0.f;
        m_Matrix[ 3 ][ 1 ] = 0.f;
        m_Matrix[ 3 ][ 2 ] = 0.f;
        m_Matrix[ 3 ][ 3 ] = 1.f;

        // Rotate the matrix
        m_Matrix = glm::rotate( m_Matrix, p_Angle, glm::vec3( 1.f, 0.f, 0.f ) );

        // Go back to the original location
        m_Matrix[ 3 ][ 0 ] = tempOrigin.x;
        m_Matrix[ 3 ][ 1 ] = tempOrigin.y;
        m_Matrix[ 3 ][ 2 ] = tempOrigin.z;
        m_Matrix[ 3 ][ 3 ] = 1.f;

        normalize( );
    }
}

如果有任何后果,我将相机矩阵视为视图矩阵(具有单独的模型矩阵 [view*model=modelview] 和透视投影矩阵)。

最后,一个典型的框架是这样的:检查输入(适当移动/旋转相机),渲染天空盒(忽略视图/相机矩阵的原点/位置列),绘制其他所有内容(考虑整个视图矩阵)。

我很抱歉提出这样一个常见的问题,但两天的搜索和尝试各种不同的解决方案没有产生积极的结果。

谢谢。

I know this is a common question (as I have read many threads on here and other forums about it) but for the life of me I can not get the camera rotation that I desire. I want the camera to be able to 'look around' and not for it to 'orbit' around a point, this point being the OpenGL origin.

I am aware that 'there is no camera in OpenGL', the terrain moves and not the viewpoint, etc. and all of those similar concepts but it has not helped me in solving this.

Unfortunately I am stubborn and want to write my code with no deprecated features and so this eliminates 99% of the similar situations I have read about since most of those solutions were with gluLook and similar functions.

The matrix class I am using is similar to the one that is used by the OpenGL SuperBible 5th Edition ( source, GLFrame.h is the main file of interest) but have adapted it to use the OpenGL Mathematics Library.

The typical response to this question is to translate to the origin, rotate, then translate back, but this does nothing for me.

Some code:

void rotateLocalX( GLfloat p_Angle )
{
    if( ( m_Roll < m_RollLimit ) && ( m_Roll > ( -m_RollLimit ) ) )
    {
        //store away the current location so I can translate back to it
        glm::vec3 tempOrigin = getOrigin( );

        m_Roll += p_Angle;

        // Go to the Origin

        //you can also subtract the current location to get to 0.f

        //also doing glm::translate( m_Matrix, -( tempOrigin ) ); -> rotate -> 
        //glm::translate( m_Matrix, tempOrigin ) has the same result
        m_Matrix[ 3 ][ 0 ] = 0.f;
        m_Matrix[ 3 ][ 1 ] = 0.f;
        m_Matrix[ 3 ][ 2 ] = 0.f;
        m_Matrix[ 3 ][ 3 ] = 1.f;

        // Rotate the matrix
        m_Matrix = glm::rotate( m_Matrix, p_Angle, glm::vec3( 1.f, 0.f, 0.f ) );

        // Go back to the original location
        m_Matrix[ 3 ][ 0 ] = tempOrigin.x;
        m_Matrix[ 3 ][ 1 ] = tempOrigin.y;
        m_Matrix[ 3 ][ 2 ] = tempOrigin.z;
        m_Matrix[ 3 ][ 3 ] = 1.f;

        normalize( );
    }
}

And if it is of any consequence, I am treating the camera matrix as the view matrix (with a separate model matrix [view*model=modelview] and a perspective projection matrix).

Finally a typical frame goes like this: check for input (move/rotate camera as appropriate), render skybox (ignoring the origin/location column of the view/camera matrix), draw everything else (taking into account the entire view matrix).

I apologize for asking such a common question but two days of searching and trying various different solutions has yielded no positive results.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

若言繁花未落 2024-11-15 19:36:27

移动“相机”相当于对模型应用逆变换。

假设您的世界中有一个以 x 点为中心的对象,其方向为旋转矩阵 R。您的世界中的 y 点还有一个相机,以旋转矩阵 S 为方向。为了在渲染对象时获得我认为您想要的结果,您需要一个如下所示的变换矩阵:

S^-1*T(-y)*T(x)*R

即,您将对象围绕对象坐标中的原点进行定向,并将其转换为世界坐标中的位置。然后平移它,使相机位于原点,最后旋转对象,使相机向下看 -z 轴。幸运的是,旋转矩阵的求逆与转置是一样的。

如果您想在以相机为中心的坐标中将相机平移c,那么您将得到x' = x + Sc。平移通过相机向前旋转而旋转。如果您想在相机坐标中按Q旋转,则可以进行后乘:S' = S*Q

如果cQ位于世界坐标中,则x' = x + cS' = Q*S


根据您对我的评论的回答,听起来您可能只是在操纵矩阵中的错误数字。有没有可能你的行和列交换了;所以你总是以 [0,0,0] 作为原点?然后将这些值返回设置为零(尽管它们没有改变)。


编辑 2:

也许您在将 m_Matrix 应用到变换矩阵之前没有对其进行反转?我认为这会产生你所描述的效果。要创建逆矩阵,您需要对旋转分量进行转置,对平移分量取反,然后将平移分量旋转旋转分量。

Moving a 'camera' is equivalent to applying the inverse transformation to the model.

Let's say you have an object centered at point x in your world, oriented with rotation matrix R. You also have a camera at point y in your world, oriented with rotation matrix S. To get what I believe is your desired result when rendering the object, you need a transformation matrix that looks like this:

S^-1*T(-y)*T(x)*R

That is, you orient the object around the origin in object coordinates, you translate it to its location in world coordinates. You then translate it so that the camera is at the origin, and finally rotate the object so that the camera is looking down the -z axis. Fortunately, inverting a rotation matrix is the same thing as taking the transpose.

If you want to translate the camera by c in camera-centered coordinates then you get x' = x + Sc. The translations are rotated by the forward camera rotation. If you want to rotate by Q in camera coordinates, then you post-multiply: S' = S*Q.

If c and Q are in world coordinates then x' = x + c and S' = Q*S.


By your answer to my comment, it sort of sounds like you might just be manipulating the wrong numbers in the matrix. Is it possible that your rows and columns are swapped; so you're always getting [0,0,0] as the origin? And then setting those values back to zero (although they're unchanged).


Edit 2:

Perhaps you're not inverting m_Matrix before applying it to the transformation matrix? I think that would create the effect you're describing. To create the inverse matrix, you will take the transpose of the rotation component, negate the translation component, and rotate the translation component by the rotation component.

烟火散人牵绊 2024-11-15 19:36:27

除了相机的位置之外,您的代码中还应该有一个方向向量。

这就是你需要旋转的。

您可能想查看矩阵变换扩展,特别是lookAt

You should have a direction vector somewhere in your code in addition to the position of the camera.

That is what you need to rotate.

You might want to look at the matrix transform extensions and in particular the lookAt

故事未完 2024-11-15 19:36:27

在构建视图矩阵时,请确保按顺序进行乘法

旋转*平移

而不是

平移*旋转

这是我解决这个问题的方法,发生在我身上

while building your view matrix make sure you are doing the multiplication in order

rotation * translation

and not

translation * rotation

this was the way I solved this problem that where happening to me

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文