我正在使用带有固定功能管道的opengl 2.0。似乎在opengl 2.0中 他们推动顶点通过模型 - 视图堆栈,这基本上是(视图矩阵*模型矩阵),其中模型矩阵不提供任何转换,实际上它带来一个对象说一个立方体以(0,0,0)为中心)如果模型视图矩阵加载了单位矩阵,那么它自己的相机将位于(0,0,0)向下看负z轴。
因此,如果我使用立方体的翻译调用,我真的在眼睛空间中移动立方体吗?
据我所知,广义的观看管道是
顶点 - >建模矩阵 - >世界空间,世界空间中的物体 - >查看矩阵 - >眼睛空间,眼睛空间物体 - >投影矩阵 - >剪辑空间,然后归一化等
所以如果我切换到 模型视图矩阵栈() loadidentity() gltranslate(负z方向上升5个单位) gldrawcube()
它会根据翻译将立方体从眼睛空间的中心移开吗?
我认为我的困惑在于,我不知道程序启动时加载到模型视图矩阵堆栈中的内容,我认为它是一个将所有内容都带到眼睛空间中心的单位矩阵。
答案 0 :(得分:2)
在新创建的OpenGL上下文中,所有矩阵都是标识,即向量经过未转换。在固定功能中,OpenGL顶点转换会跳过“世界”步骤,将对象→世界和世界→眼睛折叠成单个转换。然而,这没什么大不了的。无论如何,照明计算在眼睛空间中是最容易的。由于固定功能OpenGL不知道着色器(除了扩展名),因此不需要在世界空间中做任何事情。
glTranslate,glRotate,glScale 不转换对象。他们操纵堆栈顶部的矩阵以进行操作。因此,最终它们有助于转换,但不是对象,而是顶点(位置)级别。
它会根据平移从眼睛空间的中心移动立方体吗?
确实,但是“移动”(实际上是变形的)是立方体的顶点;它可能不仅仅是一种翻译。
由于评论而编辑
要理解的关键是转型构成。首先,转换是一种映射
T: R^4 -> R^4, v' = v |-> T(v)
有一个变换的子集,即可以用矩阵乘法表示的线性变换:
v' = T * v
可以连接变换,即v = v |-> T'○T (v)
再次为线性变换子集,以矩阵形式编写,你可以将其扩展为
v' = T * v
v'' = T' * v'
=>
v'' = T' * T * v
现在让V
表示观看变换,W
表示世界变换。所以总变换是
M = V * W
矩阵乘法的顺序(即矩阵乘法不可交换):
∃ M, N ∊ {Matrices}: M * N ≠ N * M
视图变换V
是整个世界的变换,因此它以某种方式移动,即世界中的相机最终位于原点,查看负Z轴。因此,让V'
成为将“相机”从原点移动到世界各地的变换,该运动的反转使得世界以相机停留在原点的方式移动世界。所以
V = inv(V')
最后但并非最不重要的是给出了一些矩阵A,B,C
A = B * C
然后
inv(A) = inv(C) * inv(B)
即。操作顺序逆转。因此,如果使用反向OpenGL矩阵运算“定位”“摄像机”,则必须颠倒操作的顺序。由于操作的整体顺序很重要,因此观察转换必须在模型转换之前进行。