OpenGL的列向量和OSG的行向量
OpenGL的列向量和OSG的行向量

OpenGL的列向量和OSG的行向量
• 发表于 9个月前
• 阅读 11
• 收藏 0
• 评论 0

• 行向量和列向量

### 3.行向量和列向量的变换

（1）行向量左乘矩阵

（2）行向量右乘矩阵

（3）列向量左乘矩阵

（4）列向量右乘矩阵

• 行向量列向量以及在编程语言中的内存布局

（1）v是行向量 ， 那么  v' = v*M

（2）v是列向量，  那么  v' = M*v

I'm the one responsible for the 'column-major ordering' used in OpenGL, so I'll try to explain what's going on to try to put this discussion to rest.

First, there are two issues that seem to be confused.
One issue is how matrices are stored in memory,
and the other is whether one treats vectors as rows of coordinates or as columns.

I'll dispense with the second issue first.
Recent mathematical treatments of linear algebra and related fields invariably treat vectors as columns (there are some technical reasons for this). For some reason, this has not been the case in computer graphics, where vectors were written as rows, thus transposing everything from standard mathematical usage. When I wrote the OpenGL spec, I decided to do my part to right this heinous inconsistency. Thus the spec is written with vectors treated as columns, with a matrix correspondingly applied on the left of a column.

The one difficulty was compatibility with the current GL, where vectors had been written as rows. So I come up with this subterfuge: say that matrices in OpenGL are stored in column major order. The point is that you could rewrite the spec with everything transposed (with vectors written as rows), and everything would be exactly the same as it was, including the row major ordering of matrices.

（1）使用行向量的方式来理解， 那么我们的矩阵是

double M[4][4] =
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9,10,11,12},
{13,14,15,16}
};

（2）使用列向量的方式来理解，那么我们的矩阵就不是上面的矩阵了，而是：

double M[4][4] =
{
{1, 5, 9,  13},
{2, 6, 10, 14},
{3, 7, 11, 15},
{4, 8, 12, 16}
};

（1）使用行向量或者列向量来理解OpenGL和OSG都可以，实际上行向量和列向量并没有任何的差别

（2）当使用列向量来理解变换的时候，所有的变换方式都是后乘（右乘），当使用行向量来理解变换的时候，所有变换的方式都是前乘（左乘）

（3）OpenGL为了表现它是使用的列向量，所有的矩阵设计为列主序的方式，因此当我们在进行变换的时候，需要注意要将矩阵按C/C++语言内存布局的方式存储，也就是说假设有一个平移矩阵，平移量Tx,Ty,Tz应该处在的位置是数组的第 4,8,12位置处

（4）OSG为了让人感觉它使用的是行向量，所有矩阵的设计都是基于行主序的方式。这样的设计正好与c++语言中二维数组的存储方式一致，使用起来比较自然。所有在OSG中的变换都是左乘矩阵， 通过查看OSG中Matrix的实现也很容易看到这一点：

double xarray[4][4] =
{
{1, 2, 3,  4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
};

osg::Matrixd mat;
mat.set((double*)xarray);

//x12 = 7
double x12 = mat(1, 2);

×