2013-06-03 191 views
2

我看到这对OpenGL site:使用行主要在OpenGL着色器

OpenGL着色语言属性变量被允许是类型MAT2,MAT3,或MAT4的。这些类型的属性可以使用glVertexAttrib入口点加载。矩阵必须以列的主要顺序加载到连续的通用属性槽中,每个通用属性槽中的矩阵有一列。

我一直在使用基于row-major的矢量库。即,4×4矩阵的16个元件中的结构体被布局是这样的:

vec4 x; 
vec4 y; 
vec4 z; 
vec4 w; 

当每个vec4具有组件x, y, z, w,因此线性顺序的内容是行主由于第一行占据先在存储器4点的位置,并且矩阵数学作为这样处理,例如此旋转变换:

static Matrix4<T> RotateZ(T degrees) 
{ 
    T radians = degrees * 3.14159f/180.0f; 
    T s = std::sin(radians); 
    T c = std::cos(radians); 

    Matrix4 m; 
    m.x.x = c; m.x.y = s; m.x.z = 0; m.x.w = 0; 
    m.y.x = -s; m.y.y = c; m.y.z = 0; m.y.w = 0; 
    m.z.x = 0; m.z.y = 0; m.z.z = 1; m.z.w = 0; 
    m.w.x = 0; m.w.y = 0; m.w.z = 0; m.w.w = 1; 
    return m; 
} 

该库是行主支持写入的客户端代码时左到右计算,这对很多程序员来说是很自然的。但我不明白的是,这些行主矩阵是按照原样发送到着色器的,根据上面的说明,期望列专业。

我知道着色器从右到左执行计算。但是不应该将行主矩阵转置,因此在将其投影到着色器之前它是列专业的?我没有这样做,但它工作得很好。

回答

4

从你的问题来看,就OpenGL而言,矩阵的内存布局是否是行主要形式并不明显。如果矩阵的最后一个成员(w)包含矩阵表示的变换的平移分量,那么它与列主布局不可区分。

如果您在进行矩阵向量乘法时与操作数顺序一致,则可以使用GLSL中的行主矩阵。

如果你的shader代码具有乘法看起来是这样的:

vec4 v_t = vector * matrix_row_major 

这是一样的:

vec4 v_t = matrix_column_major * vector 

其中matrix_row_majormatrix_column_major

的转