OpenGL 旋转和平移

发布于 2025-01-11 01:51:41 字数 333 浏览 4 评论 0原文

我正在构建一个相机类来查看场景周围。目前我有 3 个立方体散布在周围,以便对正在发生的事情有一个良好的印象。我在鼠标上设置了滚动按钮,以便沿 z 轴进行平移,当我向左或向右移动鼠标时,我会检测到此移动并绕 y 轴旋转。这只是为了看看会发生什么并玩一下。因此,我成功地通过围绕原点旋转立方体来使相机旋转,但在我旋转某个角度后,比如说 90 度,并尝试沿 z 轴平移,令我惊讶的是,我发现我的立方体现在从左到右正确,而不是朝向我或远离我。那么这是怎么回事呢?看来z轴也旋转了。我想 x 轴也是如此。因此,看起来实际上没有任何东西相对于原点发生移动,但包含所有对象的整个坐标系只是旋转了。任何人都可以帮助我,这是怎么回事? opengl 中的坐标系如何工作?

I am building a camera class to look arround a scene. At the moment I have 3 cubes just spread arround to have a good impression of what is going on. I have set my scroll button on a mouse to give me translation along z-axis and when I move my mouse left or right I detect this movement and rotate arround y-axis. This is just to see what happens and play arround a bit. So I succeeded in making the camera rotate by rotating the cubes arround the origin but after I rotate by some angle, lets say 90 degrees, and try to translate along z axis to my surprise I find out that my cubes are now going from left to right and not towards me or away from me. So what is going on here? It seems that z axis is rotated also. I guess the same goes for x axis. So it seems that nothing actually moved in regard to the origin, but the whole coordinate system with all the objects was just rotated. Can anyone help me here, what is going on? How coordinate system works in opengl?

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

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

发布评论

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

评论(1

别靠近我心 2025-01-18 01:51:41

您很可能混淆了本地轮换和全局轮换。通常的廉价补救措施是更改(反转)某些转换的顺序。然而,盲目这样做是一种反复试验,可能会令人沮丧。最好先理解数学...

旧 API OpeGL 使用 MVP 矩阵,即:

MVP = Model * View * Projection

模型和视图已经相乘。您所拥有的很可能是相同的。现在的问题是 Model 是直接矩阵,但 View 是逆矩阵。

因此,如果您有一些表示相机的变换矩阵,以便使用它进行变换,则需要使用其逆矩阵...

MVP = Model * Inverse(Camera) * Projection

然后您可以对 Model使用相同的变换顺序相机并使用它们的几何属性,如基本向量等......然后像相机本地移动或相机跟随之类的东西就很容易了。 请注意,某些教程使用 glTranspose 而不是实数矩阵逆。仅当矩阵仅包含单位(或相等大小)正交基向量时,这才是正确的没有任何偏移,因此没有缩放、倾斜、偏移或投影,只是沿所有轴旋转和相等缩放!

这意味着当您以相同的方式旋转模型视图时,结果是相反的。因此,在旧代码中通常会有这样的内容:

// view part of matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotate3f(view_c,0,0,1); // ugly euler angles
glRotate3f(view_b,0,1,0); // ugly euler angles
glRotate3f(view_a,1,0,0); // ugly euler angles
glTranslatef(view_pos);   // set camera position
// model part of matrix
for (i=0;i<objs;i++)
    {
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glTranslatef(obj_pos[i]);   // set camera position
    glRotate3f(obj_a[i],1,0,0); // ugly euler angles
    glRotate3f(obj_b[i],0,1,0); // ugly euler angles
    glRotate3f(obj_c[i],0,0,1); // ugly euler angles
    //here render obj[i]
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    }

注意变换的顺序是相反的(我只是在编辑器中编写它,因此它没有经过测试,并且可以与本机 GL 表示法相反......我不使用欧拉角) ...顺序必须符合您的约定...要了解有关这些内容的更多信息(包括示例),不要使用无用的欧拉角,请参阅:

这是 3D 相机类的 4D 版本(只需将矩阵缩小到 4x4,并且只有 3 次旋转,而不是 6 次):

注意本地lrot_??和全局grot_??的区别功能。另请注意,旋转是由平面而不是轴向量定义的,因为轴向量只是人类的抽象,除了 2D 和 3D 之外,它实际上不起作用......平面从 2D 到 ND

PS。 这是一个好主意扭曲(缩放、倾斜)与模型分离,并保持表示坐标系正交的变换矩阵。一旦你对它们进行高级数学计算,它会简化很多事情。导致:

MVP = Model * Model_distortion * Inverse(Camera) * Projection

You are most likely confusing local and global rotations. Usual cheap remedy is to change(reverse) order of some of your transformation. However doing this blindly is trial&error and can be frustrating. Its better to understand the math first...

Old API OpeGL uses MVP matrix which is:

MVP = Model * View * Projection

Where Model and View are already multiplied together. What you have is most likely the same. Now the problem is that Model is direct matrix, but View is Inverse.

So if you have some transform matrix representing your camera in oder to use it to transform back you need to use its inverse...

MVP = Model * Inverse(Camera) * Projection

Then you can use the same order of transformations for both Model and Camera and also use their geometric properties like basis vectors etc ... then stuff like camera local movements or camera follow are easy. Beware some tutorials use glTranspose instead of real matrix Inverse. That is correct only if the Matrix contains only unit (or equal sized) orthogonal basis vectors without any offset so no scale,skew,offset or projections just rotation and equal scale along all axises !!!

That means when you rotate Model and View in the same way the result is opposite. So in old code there is usual to have something like this:

// view part of matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotate3f(view_c,0,0,1); // ugly euler angles
glRotate3f(view_b,0,1,0); // ugly euler angles
glRotate3f(view_a,1,0,0); // ugly euler angles
glTranslatef(view_pos);   // set camera position
// model part of matrix
for (i=0;i<objs;i++)
    {
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glTranslatef(obj_pos[i]);   // set camera position
    glRotate3f(obj_a[i],1,0,0); // ugly euler angles
    glRotate3f(obj_b[i],0,1,0); // ugly euler angles
    glRotate3f(obj_c[i],0,0,1); // ugly euler angles
    //here render obj[i]
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    }

note the order of transforms is opposite (I just wrote it here in editor so its not tested and can be opposite to native GL notation ... I do not use Euler angles) ... The order must match your convention... To know more about these (including examples) not using useless Euler angles see:

Here is 4D version of what your 3D camera class should look like (just shrink the matrices to 4x4 and have just 3 rotations instead of 6):

pay attention to difference between local lrot_?? and global grot_?? functions. Also note rotations are defined by plane not axis vector as axis vector is just human abstraction that does not really work except 2D and 3D ... planes work from 2D to ND

PS. its a good idea to have the distortions (scale,skew) separated from model and keep transform matrices representing coordinate systems orthonormal. It will ease up a lot of things latter on once you got to do advanced math on them. Resulting in:

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