为什么android.Matrix.setRotateMreturns一个旋转方向与预期旋转矩阵相反的矩阵?

Why android.Matrix.setRotateM returns a matrix whose rotation direction is the opposite of the expected rotation matrix?

例如,如果我给出以下参数:

float[] rotateMatrix = identityMatrix.clone();
Matrix.setRotateM(rotateMatrix, 0, 90, 0, 0, 1);

我想要一个逆时针旋转90度的矩阵,应该是:

0       -1.0     
1.0    0

但实际上返回的 rotateMatrix 是:

0       1.0    
-1.0    0

奇怪的是,渲染输出是正确的,图像逆时针(而不是顺时针)旋转了 90 度。为什么?

这是因为 OpenGL (ES) 矩阵是由按列主要顺序的向量指定的。

android.opengl.Matrix:

Matrix math utilities. These methods operate on OpenGL ES format matrices and vectors stored in float arrays.

Matrices are 4 x 4 column-vector matrices stored in column-major order:

m[offset +  0] m[offset +  4] m[offset +  8] m[offset + 12]
m[offset +  1] m[offset +  5] m[offset +  9] m[offset + 13]
m[offset +  2] m[offset +  6] m[offset + 10] m[offset + 14]
m[offset +  3] m[offset +  7] m[offset + 11] m[offset + 15]

参见 OpenGL ES Shading Language 3.20 Specification, 5.4.2 Vector and Matrix Constructors,第 110 页:

To initialize a matrix by specifying vectors or scalars, the components are assigned to the matrix elements in column-major order .

mat4(float, float, float, float,  // first column
     float, float, float, float,  // second column
     float, float, float, float,  // third column
     float, float, float, float); // fourth column

所以 GLSL mat4 可以通过轴的 4 个向量和平移来设置:

mat4 m44 = mat4(
    vec4( Xx, Xy, Xz, 0.0),
    vec4( Yx, Xy, Yz, 0.0),
    vec4( Zx  Zy  Zz, 0.0),
    vec4( Tx, Ty, Tz, 1.0) );

绕 z-axis (0, 0, 1) 向右(逆时针)数学旋转后,x 轴为 (0, 1, 0) 而 y-axis 是 (-1, 0, 0),这导致矩阵:

 0  1  0  0   // x axis vector
-1  0  0  0   // y axis vector
 0  0  1  0   // z axis vector
 0  0  0  1   // translation vector