原始问题/代码
我正在微调 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 空间的空间。这发生在两个过程中:
- Eye Space通过投影(矩阵)转换为Clip Space
- 应用透视划分 {X,Y,Z} = {x,y,z}/w,将其放入标准化设备坐标空间。
可见效果类似于 OpenGL 的“透镜”。在下图中,您可以看到眼睛空间中的绿色突出显示区域(技术上它是一个 3 体积),这是 NDC 空间反向投影到其中。在大写情况下,显示了对称平截头体的效果,即 left = -right
、top = -bottom
。在底部图片中,显示了一个不对称的平截头体,即 left ≠ -right
,top ≠ -bottom
。
请注意,应用这种不对称(通过您的中心偏移量)不会转动,即旋转您的平截头体,但会倾斜它。然而,“相机”将停留在原点,仍然指向 -Z 轴。当然,图像投影的中心会移动,但这不是您想要的。
像这样倾斜平截头体有应用。最重要的是,它是实现左右眼不同 View 和立体渲染设置的正确方法。
关于c++ - 带有移动物体的 gluLookAt 和 glFrustum,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7743821/