C ++和OpenGL矩阵顺序之间的混乱(行主要与列主要) [英] Confusion between C++ and OpenGL matrix order (row-major vs column-major)

查看:156
本文介绍了C ++和OpenGL矩阵顺序之间的混乱(行主要与列主要)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对矩阵定义感到困惑。我有一个矩阵类,它拥有一个 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}};

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];

因此, matrixB [0] = row 0, matrixB [1] = row 1,等等,这表示行主版面。



当我创建一个如下的翻译矩阵时出现问题/混乱:

  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}



然后当我调用 glUniformMatrix4fv ,我需要将转置标志设置为GL_FALSE,表明它是列主,否则转换,如translate / scale等不能正确应用:


如果转置是GL_FALSE,则假定每个矩阵以
列的主要顺序提供。如果转置是GL_TRUE,假定每个矩阵以行主要顺序提供


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

解决方案

opengl文档中使用的矩阵符号不描述OpenGL矩阵的内存中布局



如果你放弃/忘记整个row / column-major的话,那会更容易。这是因为除了行/列主要之外,程序员还可以决定除了符号之外,他还想如何在存储器中布置矩阵(相邻元素是否形成行或列),这增加了混乱。 p>

OpenGL矩阵具有同一个内存布局作为直接矩阵

  xx xy xz 0 
yx yy yz 0
zx zy zz 0
px py pz 1

  {xx xy xz 0 yx yy yz 0 zx zy zz 0 px py pz 1} 




  • x,y,z是描述矩阵坐标系(相对于全局坐标系的局部坐标系)


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

    这意味着转换矩阵应该按如下方式布置在内存中:

      {1,0,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节所述。



    Column-major和row-major纯粹是一个符号约定。注意,用列主矩阵进行后乘法产生与用行 - 主矩阵进行前乘法相同的结果。 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矩阵顺序之间的混乱(行主要与列主要)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆