c++ - 带有移动物体的 gluLookAt 和 glFrustum

标签 c++ opengl

原始问题/代码

我正在微调 3D 对象的渲染并尝试使用 gluLookAt 实现相机跟随对象,因为对象的中心 y 位置一旦达到其最大高度就会不断增加。下面是我设置 ModelView 和投影矩阵的代码部分:

float diam = std::max(_framesize, _maxNumRows);
float centerX = _framesize / 2.0f;
float centerY = _maxNumRows / 2.0f + _cameraOffset;
float centerZ = 0.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(centerX - diam,
          centerX + diam,
          centerY - diam,
          centerY + diam,
          diam,
          40 * diam);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0., 0., 2. * diam, centerX, centerY, centerZ, 0, 1.0, 0.0);

目前,该对象显示在很远的地方,并且似乎进一步向后移动到屏幕 (-z) 并向下移动 (-y),直到它最终消失。

我做错了什么?如何让我的表面出现在屏幕中央,占据整个 View ,并且相机随着对象的更新而移动?


更新的代码和当前问题

这是我当前的代码,它现在将对象置于死点并填满我的窗口。

float diam = std::max(_framesize, _maxNumRows);
float centerX = _framesize / 2.0f;
float centerY = _maxNumRows / 2.0f + _cameraOffset;
float centerZ = 0.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(centerX - diam,
          centerX,
          centerY - diam,
          centerY,
          1.0,
          1.0 +  4 * diam);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(centerX, _cameraOffset, diam, centerX, centerY, centerZ, 0, 1.0, 0.0);

当被查看的对象开始移动时,我仍然遇到一个问题,它没有保持完美居中。更新时,它似乎几乎向上抖动了一个像素,然后向下抖动了 2 个像素。最终对象离开当前 View 。我该如何解决这种抖动?

最佳答案

您的问题在于理解投影的作用。在您的情况下 glFrustum。我认为解释 glFrustum 的最佳方式是通过图片(我只是手绘)。您从一个名为 Eye Space 的空间开始。它是您的顶点在被 modelview 矩阵变换后所在的空间。这个空间需要转换成一个叫做Normalized Device Coordinates 空间的空间。这发生在两个过程中:

  1. Eye Space通过投影(矩阵)转换为Clip Space
  2. 应用透视划分 {X,Y,Z} = {x,y,z}/w,将其放入标准化设备坐标空间。

可见效果类似于 OpenGL 的“透镜”。在下图中,您可以看到眼睛空间中的绿色突出显示区域(技术上它是一个 3 体积),这是 NDC 空间反向投影到其中。在大写情况下,显示了对称平截头体的效果,即 left = -righttop = -bottom。在底部图片中,显示了一个不对称的平截头体,即 left ≠ -righttop ≠ -bottom

The effect of glFrustum

请注意,应用这种不对称(通过您的中心偏移量)不会转动,即旋转您的平截头体,但会倾斜它。然而,“相机”将停留在原点,仍然指向 -Z 轴。当然,图像投影的中心会移动,但这不是您想要的。

像这样倾斜平截头体有应用。最重要的是,它是实现左右眼不同 View 和立体渲染设置的正确方法。

关于c++ - 带有移动物体的 gluLookAt 和 glFrustum,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7743821/

相关文章:

c++ - 是否尝试修改 const_cast-ed,但动态分配的常量对象仍然是未定义的行为?

c++ - 运行时链接错误 : The procedure entry point glewInit@0 could not be located

c++ - Arcsynthesis OpenGL 3.3 教程的问题 - MAKE 错误

c++ - cmake force parallel .C.o 链接前编译

c++ - ActiveX OCX 在 Release模式下构建时可以注册,但在 Debug模式下不能注册

c++ - 插入要设置的 vector 项

c++ - 无法弄清楚为什么我的 Print Array 正在替换元素

opengl 3.3 z-fighting 正交 2d View

c++ - glDrawRangeElements 不绘制所选范围

c++ - 在没有窗口的windows桌面上绘制OpenGL