C++ C和x2B之间的混淆+;和OpenGL矩阵顺序(行主要与列主要)

C++ C和x2B之间的混淆+;和OpenGL矩阵顺序(行主要与列主要),c++,math,opengl,matrix,C++,Math,Opengl,Matrix,我对矩阵的定义感到非常困惑。我有一个矩阵类,它包含一个float[16],根据以下观察,我假设它是row-major: float matrixA[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; float matrixB[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } }; matrixA和matrixB

我对矩阵的定义感到非常困惑。我有一个矩阵类,它包含一个
float[16]
,根据以下观察,我假设它是row-major:

float matrixA[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
float matrixB[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
matrixA
matrixB
在内存中都具有相同的线性布局(即所有数字都按顺序排列)。根据此指示行主要布局

matrixA[0] == matrixB[0][0];
matrixA[3] == matrixB[0][3];
matrixA[4] == matrixB[1][0];
matrixA[7] == matrixB[1][3];
因此,
matrixB[0]
=第0行,
matrixB[1]
=第1行等。同样,这表示行主布局

matrixA[0] == matrixB[0][0];
matrixA[3] == matrixB[0][3];
matrixA[4] == matrixB[1][0];
matrixA[7] == matrixB[1][3];
当我创建一个翻译矩阵时,我的问题/困惑出现了,该矩阵如下所示:

1, 0, 0, transX
0, 1, 0, transY
0, 0, 1, transZ
0, 0, 0, 1
它在内存中的布局是,
{1,0,0,transX,0,1,0,transY,0,0,1,transZ,0,0,0,1}

然后,当我调用时,我需要将转置标志设置为GL_FALSE,表示它是列主,否则转换(如translate/scale等)无法正确应用:

如果转置为GL_FALSE,则假定每个矩阵以 列主要顺序。如果转置为GL_TRUE,则假定每个矩阵 按主要订单提供


为什么我的矩阵(看起来是行主矩阵)需要作为列主矩阵传递给OpenGL?

OpenGL文档中使用的矩阵表示法没有描述OpenGL矩阵的内存布局

如果你认为放弃/忘记整个“行/列主调”会更容易。这是因为除了行/列主键之外,程序员还可以决定如何在内存中布局矩阵(相邻元素是否形成行或列),除了符号之外,这会增加混乱

OpenGL矩阵已经实现

  • x、 y、z是描述矩阵坐标系(相对于全局坐标系的局部坐标系)的三分量向量

  • p是描述矩阵坐标系原点的三分量向量

这意味着翻译矩阵应该在内存中按如下方式排列:

{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, transX, transY, transZ, 1 }.
就这样吧,剩下的就容易了

---引用自旧opengl常见问题解答--


9.005 OpenGL矩阵是以列为主还是以行为主

出于编程目的,OpenGL矩阵是16值数组,其基向量在内存中连续排列。翻译组件占据16个元素矩阵的第13、14和15个元素,其中索引从1到16进行编号,如OpenGL 2.1规范第2.11.2节所述

列主键与行主键纯粹是一种符号约定。请注意,与列主矩阵相乘后产生的结果与与与行主矩阵相乘前产生的结果相同。OpenGL规范和OpenGL参考手册都使用列主符号。你可以使用任何符号,只要清楚地说明

不幸的是,在规范和蓝皮书中使用列主格式已经在OpenGL编程社区中造成了无尽的混乱。列主符号表示矩阵并不像程序员期望的那样在内存中布局


opengl文档中使用的矩阵表示法不描述opengl矩阵的内存布局

如果你认为放弃/忘记整个“行/列主调”会更容易。这是因为除了行/列主键之外,程序员还可以决定如何在内存中布局矩阵(相邻元素是否形成行或列),除了符号之外,这会增加混乱

OpenGL矩阵已经实现

  • x、 y、z是描述矩阵坐标系(相对于全局坐标系的局部坐标系)的三分量向量

  • p是描述矩阵坐标系原点的三分量向量

这意味着翻译矩阵应该在内存中按如下方式排列:

{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, transX, transY, transZ, 1 }.
就这样吧,剩下的就容易了

---引用自旧opengl常见问题解答--


9.005 OpenGL矩阵是以列为主还是以行为主

出于编程目的,OpenGL矩阵是16值数组,其基向量在内存中连续排列。翻译组件占据16个元素矩阵的第13、14和15个元素,其中索引从1到16进行编号,如OpenGL 2.1规范第2.11.2节所述

列主键与行主键纯粹是一种符号约定。请注意,与列主矩阵相乘后产生的结果与与与行主矩阵相乘前产生的结果相同。OpenGL规范和OpenGL参考手册都使用列主符号。你可以使用任何符号,只要清楚地说明

不幸的是,在规范和蓝皮书中使用列主格式已经在OpenGL编程社区中造成了无尽的混乱。列主符号表示矩阵并不像程序员期望的那样在内存中布局



您正在处理两个不同的问题

首先,您的示例涉及内存布局。您的[4][4]数组是行主数组,因为您使用了C多维数组建立的约定来匹配您的线性数组

第二个问题是关于如何在程序中解释矩阵的约定问题glUniformMatrix4fv用于设置着色器参数。是否为行向量列向量变换计算变换取决于如何在着色器代码中使用矩阵。因为您说需要使用列向量,所以我假设着色器代码使用矩阵A和列向量x来计算x'=A x

我认为glUniformMatrix的文档
mat4 T; vec4 v; vec4 v_transformed; 
v_transformed = T*v;
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, transX, transY, transZ, 1 }
v_transformed = v*T;
{ 1, 0, 0, transX, 0, 1, 0, transY, 0, 0, 1, transZ, 0, 0, 0, 1 }