問題描述
我對矩陣定義感到非常困惑.我有一個矩陣類,它包含一個 float[16]
,我認為它是行優先的,基于以下觀察:
float matrixA[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };浮點矩陣B[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
matrixA
和 matrixB
在內存中都具有相同的線性布局(即所有數字都按順序排列).根據 http://en.wikipedia.org/wiki/Row-major_order 這表示行主要布局.
matrixA[0] == matrixB[0][0];矩陣A[3] == 矩陣B[0][3];矩陣A[4] == 矩陣B[1][0];矩陣A[7] == 矩陣B[1][3];
因此,matrixB[0]
= 第 0 行,matrixB[1]
= 第 1 行,等等.同樣,這表示行優先布局.
當我創建一個如下所示的翻譯矩陣時,我的問題/困惑就出現了:
1, 0, 0, transX0, 1, 0, transY0, 0, 1, 反Z0, 0, 0, 1
在內存中的布局為,{ 1, 0, 0, transX, 0, 1, 0, transY, 0, 0, 1, transZ, 0, 0, 0, 1 }
.
然后當我調用 glUniformMatrix4fv 時,我需要將轉置標志設置為 GL_FALSE, 表明它是列優先的,否則轉換/縮放等轉換無法正確應用:
<塊引用>如果轉置為 GL_FALSE,則假定每個矩陣都在列主要訂單.如果轉置為 GL_TRUE,則假設每個矩陣為以行主要順序提供.
為什么我的矩陣看起來是行優先的,但需要作為列優先傳遞給 OpenGL?
opengl 文檔中使用的矩陣表示法沒有描述 OpenGL 矩陣的內存布局
如果您認為放棄/忘記整個行/列主要"的事情會更容易.那是因為除了行/列專業之外,程序員還可以決定他希望如何在內存中布置矩陣(相鄰元素形成行還是列),除了符號之外,這增加了混亂.>
OpenGL 矩陣具有與 directx 矩陣相同的內存布局.
x.x x.y x.z 0y.x y.y y.z 0z.x z.y z.z 0p.x p.y p.z 1
或
{ 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 }
x、y、z 是描述矩陣坐標系(相對于全局坐標系內的局部坐標系)的 3 分量向量.
p 是描述矩陣坐標系原點的 3 分量向量.
這意味著翻譯矩陣應該像這樣在內存中布局:
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, transX, transY, transZ, 1 }.
就這樣吧,剩下的就很簡單了.
---引自舊的opengl faq--
<小時><塊引用>9.005 OpenGL 矩陣是列優先還是行優先?
出于編程目的,OpenGL 矩陣是 16 值數組,基向量在內存中連續排列.平移分量占據了 16 元素矩陣的第 13、14 和 15 個元素,其中索引從 1 到 16 編號,如 OpenGL 2.1 規范的第 2.11.2 節所述.
列優先與行優先純粹是一種符號約定.請注意,使用列主矩陣進行后乘會產生與使用行主矩陣進行預乘相同的結果.OpenGL 規范和 OpenGL 參考手冊都使用列優先表示法.您可以使用任何符號,只要清楚說明即可.
遺憾的是,規范和藍皮書中使用列優先格式導致 OpenGL 編程社區無休止的混亂.列優先表示法表明矩陣并不像程序員所期望的那樣在內存中布置.
<小時>
I'm getting thoroughly confused over matrix definitions. I have a matrix class, which holds a float[16]
which I assumed is row-major, based on the following observations:
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
and matrixB
both have the same linear layout in memory (i.e. all numbers are in order). According to http://en.wikipedia.org/wiki/Row-major_order this indicates a row-major layout.
matrixA[0] == matrixB[0][0];
matrixA[3] == matrixB[0][3];
matrixA[4] == matrixB[1][0];
matrixA[7] == matrixB[1][3];
Therefore, matrixB[0]
= row 0, matrixB[1]
= row 1, etc. Again, this indicates row-major layout.
My problem / confusion comes when I create a translation matrix which looks like:
1, 0, 0, transX
0, 1, 0, transY
0, 0, 1, transZ
0, 0, 0, 1
Which is laid out in memory as, { 1, 0, 0, transX, 0, 1, 0, transY, 0, 0, 1, transZ, 0, 0, 0, 1 }
.
Then when I call glUniformMatrix4fv, I need to set the transpose flag to GL_FALSE, indicating that it's column-major, else transforms such as translate / scale etc don't get applied correctly:
If transpose is GL_FALSE, each matrix is assumed to be supplied in column major order. If transpose is GL_TRUE, each matrix is assumed to be supplied in row major order.
Why does my matrix, which appears to be row-major, need to be passed to OpenGL as column-major?
matrix notation used in opengl documentation does not describe in-memory layout for OpenGL matrices
If think it'll be easier if you drop/forget about the entire "row/column-major" thing. That's because in addition to row/column major, the programmer can also decide how he would want to lay out the matrix in the memory (whether adjacent elements form rows or columns), in addition to the notation, which adds to confusion.
OpenGL matrices have same memory layout as directx matrices.
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
or
{ 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 }
x, y, z are 3-component vectors describing the matrix coordinate system (local coordinate system within relative to the global coordinate system).
p is a 3-component vector describing the origin of matrix coordinate system.
Which means that the translation matrix should be laid out in memory like this:
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, transX, transY, transZ, 1 }.
Leave it at that, and the rest should be easy.
---citation from old opengl faq--
9.005 Are OpenGL matrices column-major or row-major?
For programming purposes, OpenGL matrices are 16-value arrays with base vectors laid out contiguously in memory. The translation components occupy the 13th, 14th, and 15th elements of the 16-element matrix, where indices are numbered from 1 to 16 as described in section 2.11.2 of the OpenGL 2.1 Specification.
Column-major versus row-major is purely a notational convention. Note that post-multiplying with column-major matrices produces the same result as pre-multiplying with row-major matrices. The OpenGL Specification and the OpenGL Reference Manual both use column-major notation. You can use any notation, as long as it's clearly stated.
Sadly, the use of column-major format in the spec and blue book has resulted in endless confusion in the OpenGL programming community. Column-major notation suggests that matrices are not laid out in memory as a programmer would expect.
這篇關于C++ 和 OpenGL 矩陣順序之間的混淆(行優先 vs 列優先)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!