在我们使用OpenGL和OSG的过程中,总会涉及到顶点坐标以及坐标的变换(通过向量和矩阵相乘),这其中经常会看到有人说在OpenGL中使用的是列向量,在OSG中使用的是行向量 ,由于行向量和列向量的不同导致在矩阵作乘法的时候有左乘和右乘之分,本文就这一问题作一个相对完整的解释。
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.
double M[4][4] =
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9,10,11,12},
{13,14,15,16}
};
double M[4][4] =
{
{1, 5, 9, 13},
{2, 6, 10, 14},
{3, 7, 11, 15},
{4, 8, 12, 16}
};
通过矩阵乘法,
v' = Mv
glLoadTransposeMatrixf
glLoadTransposeMatrixd
(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);