Mar*_*ram 71 c++ opengl math matrix
我对矩阵定义感到非常困惑.我有一个矩阵类,它float[16]
根据以下观察结果保存一个我认为是行主要的:
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 } };
Run Code Online (Sandbox Code Playgroud)
matrixA
并且matrixB
两者在内存中具有相同的线性布局(即所有数字都按顺序排列).根据http://en.wikipedia.org/wiki/Row-major_order,这表示行主要布局.
matrixA[0] == matrixB[0][0];
matrixA[3] == matrixB[0][3];
matrixA[4] == matrixB[1][0];
matrixA[7] == matrixB[1][3];
Run Code Online (Sandbox Code Playgroud)
因此,matrixB[0]
= row 0,matrixB[1]
= row 1等.再次,这表示行主要布局.
当我创建一个如下所示的翻译矩阵时,我的问题/困惑就出现了:
1, 0, 0, transX
0, 1, 0, transY
0, 0, 1, transZ
0, 0, 0, 1
Run Code Online (Sandbox Code Playgroud)
这在记忆中被列为,{ 1, 0, 0, transX, 0, 1, 0, transY, 0, 0, 1, transZ, 0, 0, 0, 1 }
.
然后,当我调用glUniformMatrix4fv时,我需要将转置标志设置为GL_FALSE,表示它是列主要的,否则转换如翻译/缩放等不能正确应用:
如果转置为GL_FALSE,则假定每个矩阵按列主要顺序提供.如果转置为GL_TRUE,则假定每个矩阵按行主要顺序提供.
为什么我的矩阵似乎是行主要的,需要作为列主要传递给OpenGL?
Sig*_*erm 66
opengl文档中使用的矩阵表示法没有描述OpenGL矩阵的内存中布局
如果你认为放弃/忘记整个"行/列主要"的事情会更容易.这是因为除了行/列专业之外,程序员还可以决定他如何在内存中布置矩阵(相邻元素是否形成行或列),以及符号,这会增加混乱.
OpenGL矩阵具有与directx矩阵相同的内存布局.
x.x x.y x.z 0
y.x y.y y.z 0
z.x z.y z.z 0
p.x p.y p.z 1
Run Code Online (Sandbox Code Playgroud)
要么
{ x.x x.y x.z 0 y.x y.y y.z 0 z.x z.y z.z 0 p.x p.y p.z 1 }
Run Code Online (Sandbox Code Playgroud)
x,y,z是描述矩阵坐标系的3分量矢量(相对于全局坐标系的局部坐标系).
p是描述矩阵坐标系原点的3分量矢量.
这意味着翻译矩阵应该像这样在内存中布局:
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, transX, transY, transZ, 1 }.
Run Code Online (Sandbox Code Playgroud)
把它留在那,其余的应该很容易.
---引用旧的opengl faq--
9.005 OpenGL矩阵是专列还是行专业?
出于编程目的,OpenGL矩阵是16值数组,其基本向量在内存中连续排列.转换组件占据16元素矩阵的第13,14和15个元素,其中索引编号为1到16,如OpenGL 2.1规范的2.11.2部分所述.
列主要与行主要纯粹是一种符号约定.请注意,使用列主矩阵进行后乘法会产生与使用行主矩阵预乘的结果相同的结果.OpenGL规范和OpenGL参考手册都使用列主要表示法.只要明确说明,您可以使用任何表示法.
遗憾的是,在规范和蓝皮书中使用列主格式导致了OpenGL编程社区的无休止的混乱.列主要表示法表明矩阵不像程序员所期望的那样在内存中布局.
Rob*_*rto 53
总结SigTerm和dsharlet的答案:在GLSL中转换向量的常用方法是将向量乘以变换矩阵:
mat4 T; vec4 v; vec4 v_transformed;
v_transformed = T*v;
Run Code Online (Sandbox Code Playgroud)
为了使其工作,OpenGL期望内存布局T
,如SigTerm所述,
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, transX, transY, transZ, 1 }
Run Code Online (Sandbox Code Playgroud)
这也被称为"专业专栏".但是,在着色器代码中(如注释所示),您可以通过变换矩阵右对乘矢量:
v_transformed = v*T;
Run Code Online (Sandbox Code Playgroud)
只有T
转置时才会产生正确的结果,即具有布局
{ 1, 0, 0, transX, 0, 1, 0, transY, 0, 0, 1, transZ, 0, 0, 0, 1 }
Run Code Online (Sandbox Code Playgroud)
(即'行专业').由于您已经为着色器提供了正确的布局,即row major,因此没有必要设置transpose
标记glUniform4v
.
dsh*_*let 14
您正在处理两个不同的问题.
首先,您的示例正在处理内存布局.你的[4] [4]数组是行主要因为你使用了由C多维数组建立的约定来匹配你的线性数组.
第二个问题是关于如何解释程序中的矩阵的约定问题.glUniformMatrix4fv用于设置着色器参数.是否为行向量或列向量变换计算变换是在着色器代码中如何使用矩阵的问题.因为你说你需要使用列向量,我假设你的着色器代码使用矩阵A和列向量x来计算x' = A x.
我认为glUniformMatrix的文档令人困惑.转置参数的描述是一种非常迂回的方式,只是说矩阵是转置的或不是.OpenGL本身就是将这些数据传输到着色器,无论你是否要转置它都是你应该为你的程序建立的惯例问题.
这个链接有一些很好的进一步讨论:http://steve.hollasch.net/cgindex/math/matrix/column-vec.html
归档时间: |
|
查看次数: |
51206 次 |
最近记录: |