22

我试图了解在 OpenGL 中创建空间:

  1. 对象空间

  2. 世界空间

  3. 相机空间

  4. 投影空间


我对这些阶段的理解是否正确?

  1. “立方体”正在笛卡尔坐标系的中心创建,直接在程序内部输入顶点坐标。

  2. 坐标转换为“世界”内部的坐标,这意味着将其移动到屏幕上的任何位置。

好吧,实际上我希望您检查一下我对这两个术语的理解。


现在,我正在黑屏上创建一个三角形。openGL 代码如何适应这些空间?

默认情况下它适用于GL_MODELVIEW标志,但这是第二阶段 - 世界空间。这是否意味着调用glVertex3f()会在对象空间中创建一个三角形?

世界空间部分在哪里?


另外,我读到最后两个空格不是 openGL 管道的一部分(或其他任何名称)。但是,OpenGL 包含诸如 之类的标志GL_PROJECTION,例如:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h); // w - width, h - height
gluPerspective(45, ratio, 1, 100); // radio = w/h
glMatrixMode(GL_MODELVIEW);

这段代码有什么作用?它设定了视角。它会创建 z 轴吗?但它不是已经是对象空间部分了吗?

4

1 回答 1

44

1) 对象空间是对象的顶点相对于对象的原点。对于 1x1x1 立方体,您的顶点将是:

( 0.5,  0.5, 0.5)
(-0.5,  0.5, 0.5)
( 0.5, -0.5, 0.5)
(-0.5, -0.5, 0.5)

等等

2) 世界空间是对象在您的世界中的位置。如果您希望这个立方体位于(15, 10),您将创建一个平移矩阵,当与每个顶点相乘时,您的顶点将以 为中心(15, 10)。例如,第一个顶点将变为(15.5, 10.5, 0.5)。从对象到世界空间的矩阵称为“模型”矩阵。

3)眼睛空间(有时称为相机空间)是相对于观察者位置的世界。由于这必须是每个顶点乘以的矩阵,因此从技术上讲,它是相机方向的倒数。也就是说,如果您想要一个位于 的相机(0, 0, -10),您的“视图”矩阵必须是 的翻译(0, 0, 10)。这样一来,世界上的所有物体都向前 10 个单位,让您看起来像是向后 10 个单位。

4)投影空间是我们如何将正确的透视应用于场景(假设您没有使用正交投影)。这几乎总是由平截头体表示,本文可以比我更好地解释这一点。本质上,您是将 3d 空间映射到另一个倾斜空间。

OpenGL 然后处理剪辑空间和屏幕空间。


默认情况下它适用于GL_MODELVIEW标志,但这是第二阶段 - 世界空间。这是否意味着调用glVertex3f()会在对象空间中创建一个三角形?

glVertex3f()您总是在对象空间中设置顶点。(这实际上是一种非常古老且缓慢的方法,但这并不是这个问题的重点)

当您设置GL_MODELVIEW时,它只会更改模型矩阵(可以使用glLoadMatrixglTranslateglRotateglScale等进行操作)。


逐行,您的代码正在执行以下操作:

  1. 现在所有的变换都会影响投影矩阵。
  2. 清除旧的投影矩阵并将其替换为单位矩阵。
  3. 使用整个屏幕作为视口。
  4. 将投影矩阵设置为具有 45 度垂直视场的透视图,纵横比为 w/h,近剪辑平面 1 个单位远,远剪辑平面 100 个单位远。
  5. 现在,所有转换都再次影响模型视图矩阵。

Z 轴已经存在,这只是设置为您提供透视的投影矩阵,告诉 OpenGL 使用整个窗口进行渲染。这不是对象空间,而是将对象空间转换为投影空间的方式。


附带说明一下,您使用的是非常非常旧的 OpenGL(1992 年旧)。glTranslate 等在很久以前就被弃用了,现在刚刚从 API 中删除。您仍然可以使用它们的唯一原因是驱动程序为了兼容性而将它们保留在那里。我建议您考虑使用现代(3.0+)OpenGL。现代图形管道比立即模式(glBegin、glVertex、glEnd)快几个数量级。

于 2013-04-25T23:19:54.503 回答