OpenGL列主元矩阵的运算

代码中使用列主元还是行主元?当然都可以。如果是行主元,在void glUniformMatrix4x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);中transpose是GL_TRUE。无论是行主元还是列主元,在glUniformMatrix4fv的作用下,都统一为列主元,因此着色器代码是相同的。读法是先读列再读行,比如glUniformMatrix2x4fv的意思是要传入一个2列4行的矩阵。

经常会遇到例子代码的主元和自己工程的主元不一致的情况,如何进行调整?

举个例子:Assimp里对矩阵的读取的aiMatrix4x4t矩阵是行主元的,要读进(列主元的)glm::mat4中,需要做一个transpose转置操作,将行主元变为列主元。

如果例子代码里有的:aiMatrix4x4t mx = m1 * m2 * m3;//m1, m2, m3都为行向量,那么在glm的环境下应该怎么做呢:

m1 = glm::transpose(m1);

m2 = glm::transpose(m2);

m3 = glm::transpose(m3);

glm::mat4 mx = m1 * m2 * m3;//为什么不是m3 * m2 * m1?不是(A*B)T=(B)T * (A)T吗?

因为在glm中,m1 * m2的计算是拿m1的第i列与m2的第j行相乘,并不是像行矩阵里的规则m1的第i行和m2的第j列相乘。下面是矩阵的等价运算规则。GL_FALSE是指的glUniformMatrix4x4fv的transpose参数。你们可以使用1*2和2*3的矩阵测试一下,比较清晰。

项之间的乘积 m1,m2为行主矩阵 (m1)T,(m2)T为列主矩阵
左边的i行x右边的j列 m1*m2,GL_TRUE (m2)T*(m1)T,GL_FALSE
左边的i列x右边的j行

m2*m1,GL_TRUE 

(m1)T*(m2)T,GL_FALSE

注意:存储都是以行进行存储的。这里不是说用行依次存储每一列,而是用行存储每一列的相应行的项。比如一个列主元矩阵是由4个列向量构成(a11, a12, a13, a13), (a21, a22, a23 ,a24), (a31, a32, a33, a34), (a41, a42, a43, a44),那么存储的时候是以数组(a11, a21, a31, a41), (a12, a22, a32, a42), (a13, a23, a33, a43), (a14, a24, a34, a44)存储,通过glUniformMatrix4fv传递的数据序列为(a11, a21, a31, a41, a12, a22, a32, a42, a13, a23, a33, a43, a14, a24, a34, a44),在传递到shader时,还原为列向量形式,然后与顶点等进行乘积。在instance效果中,将matrxi的每一行作为顶点属性,在shader中依然还原为列向量的矩阵。顶点向量被认为是行向量。

上一篇:[SAP ABAP开发技术总结]增强Enhancement


下一篇:[转]一步一步玩控件:自定义TabControl——从山寨Safari开始