如何将本地对象坐标转换为世界坐标?
首先,一些背景。在3D图形,你需要担心的几个向量空间:
- 模型空间 - 这是通常的坐标你指定的OpenGL
- 世界空间 - 坐标相对于世界上一些中心点指定。
- 视图空间 - 相对于相机指定坐标
- 投影空间 - 屏幕上的所有内容适用于每个维度的间隔
[-1, +1]
。
坐标被指定为均匀,所以每个矢量都有组件(x, y, z, w)
,其中w
是比例因子。您可以使用(x/w, y/w, z/w)
获得三维坐标。缩放因子对于某些转换(比如透视投影)来说是必需的,而这对于非均匀坐标是不可能的。
需要4x4矩阵来将坐标从一个向量空间转换到另一个向量空间。你可以有三种不同的矩阵:
- 模型矩阵(模型世界)
- 查看矩阵(世界查看)
- 投影矩阵(视图投影空间)
你会项目坐标C
在屏幕上使用公式:
C' = P * V * M * C
OpenGL实习生盟友维护两个矩阵:modelview(模型和视图相乘在一起)和投影。还有一个我们不担心的纹理矩阵。当您拨打glMatrixMode
时,您正在切换这些矩阵。用glLoadIdentity
替换当前矩阵与单位矩阵。使用glTranslatef
,glRotatef
或gluProjection
等函数对当前矩阵应用变换。这些函数中的每一个都创建了一个4x4矩阵,实现了特定的变换,然后将当前矩阵乘以它。您可以看到OpenGL 2.1 reference pages中的转换矩阵。
现在为实际的答案。您需要为场景中的每个对象维护一个4x4模型矩阵。模型矩阵将包含将模型坐标转换为世界坐标所需的所有转换。举例来说,每次调用glTranslate
时候,你会更新你的模型矩阵:
T = [ 1 0 0 x ]
[ 0 1 0 y ]
[ 0 0 1 z ]
[ 0 0 0 1 ]
M' = M * T
然后你可以用你的模型矩阵得到坐标转换成世界空间(确保它们是齐次坐标第一;刚刚成立w = 1
,如果他们不是):
V' = V * M
由于要维持这些并行转换,你实际上并不需要再维持了OpenGL模型视图矩阵。您可以将您的模型矩阵作为统一传递给着色器。您可以用类似的方式维护自己的视图和投影矩阵。这在最新版本的OpenGL中是必需的;所有的矩阵处理函数都被弃用。
我该如何维护我自己的模型矩阵? – 2011-05-06 17:15:55
@Shazad,增加了一些背景信息和更详细的解释。希望有所帮助。 – 2011-05-06 17:48:11
@Jay:首先你说'C'= P * V * M * C',然而,在你说'V'= M * V'的结尾。我有点困惑,因为一旦它是'V * M'并且一次'M * V'。矩阵乘法不可交换,所以'A * B!= B * A'。难道你的答案中的任何一个顺序都是错误的?也许这也是我的数学错误,但在这种情况下,请随时纠正我。 – Mecki 2012-05-21 18:11:30
您可以使用虚拟摄像机视图矩阵(V-1)倍的对象模型视图矩阵(V * M)来获得世界坐标的倒数的产品。
你只是gluLookAt()函数使用后获得五:
glGetFloatv(GL_MODELVIEW_MATRIX,camViewMatrix)
然后反矩阵和存储,(用于乘后面的代码中)。
你在哪里,你要绘制对象点获得V *男,刚过所有的glTranslatef(),glRotatef()和glScale()使用相同的GL功能命令:
glGetFloatv(GL_MODELVIEW_MATRIX,objectsModelVie wMatrix);
V-1 *(V * 中号)== 中号
然后倍数的两个矩阵,生成的基质中包含的位置,M12 = X,M13 = y和M14 = Z
更多细节在与C语言代码: https://sourceforge.net/p/openantz/wiki/Local_to_World_Coordinates/
我建议关于线性代数或马阅读trix代数和一本关于图形的书。 – 2011-05-06 19:49:10