OpenGL中矩阵乘法的顺序

Posted

技术标签:

【中文标题】OpenGL中矩阵乘法的顺序【英文标题】:Order of matrix multiplications in OpenGL 【发布时间】:2014-01-24 00:18:29 【问题描述】:
glDisable(GL_DEPTH_TEST);
glViewport(0/*left*/, 0/*botton*/, 200/*width*/, 200/*height*/); //T4   
glMatrixMode(GL_PROJECTION);    
glLoadIdentity();   
gluPerspective(90 /*fov*/, 1/*aspect*/, 1/*fp*/, 1000/*bp*/); //T3
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity();     
gluLookAt(0/*eyex*/,0/*eyey*/,0/*eyez*/, 0/*lax*/,0/*lay*/,-1/*laz*/, 0/*upx*/,1/*upy*/,0/*upz*/); //T2
glTranslatef(-15.0, -10.0, -49.0); //T1
glBegin(GL_POINTS);
glVertex4f(0, 0, -1, 1);
glEnd();

给定这段代码,矩阵乘法以什么顺序发生?我必须知道什么才能遵循和验证纸上的计算?

我怀疑是按照顺序执行的,但还没有找到验证它的方法: v=[0,0,-1,1]

T4 * T3 * T2 * T1 * v

这对吗?

【问题讨论】:

所以在这种情况下,视口只是重新缩放并从 -1..+1 转换为 0..200。 【参考方案1】:

这大部分是正确的,但是glViewport (...) 本身并没有定义矩阵。这是一个简单的偏置和缩放操作。它定义了 X 和 Y 中的总宽度、高度和偏移量。您还缺少另一个组件,即深度范围。

乘法以该顺序发生,但由于这些是列主矩阵和后乘矩阵,因此从概念上讲,您从右侧开始,然后向左移动。划掉T4,因为它本身不是一个矩阵,而这一切的最终结果是一个剪辑空间顶点坐标。您仍然需要将v.xyz 除以v.w,然后进行视口转换以完全复制 GL 所做的工作。

可以使用矩阵实现视口变换,但您还需要考虑glDepthRange (...),它将 Z 坐标从 NDC 空间偏移和缩放到窗口空间。

这是这样一个矩阵的样子:

    

4.1 Coordinates Transformation 下更详细地讨论了整个过程。

【讨论】:

@Kalevi:我链接到的网站有一些问题,尤其是关于剪辑量的讨论。在 GL 中,我们在各个方向都有一个 [-1,1] 的 NDC 体积。在 D3D 中,XY 为 [-1,1],Z 为 [0,1]。This site 更准确,但不如视觉效果好,并且缺少对视口变换矩阵的讨论(这对于 OpenGL 也是错误的,因为 Y 不是那样倒置的)。 @Kalevi:因此,它应该是h/2 not -h/2(maxZ-minZ)/2maxZ + minZ/2 not minZ。我将尝试找到一篇更好的文章以链接到明天。如果您在实际实施我所讨论的内容时遇到问题,请随时给我留言。

以上是关于OpenGL中矩阵乘法的顺序的主要内容,如果未能解决你的问题,请参考以下文章

opengl矩阵乘法

OpenGL矩阵乘法C++

围绕对象旋转的矩阵乘法opengl

3D 空间中的 OpenGL 2D 文本 [C++/GLM] 矩阵乘法

矩阵和向量的乘法顺序

解题(JuZhengCalculate-矩阵乘法计算量)