matrix
平移:
缩放:
旋转:
Consider the two cases:
m11 m12 m13 m14 x
m21 m22 m23 m24 y
m31 m32 m33 m34 z
m41 m42 m43 m44 1
Case 1: column vector on the right
m11 m12 m13 m14
m21 m22 m23 m24
x y z 1
m31 m32 m33 m34
m41 m42 m43 m44
Case 2: row vector on the left
第一种为opengl,第二种为DirectX.第一种为矩阵在前,第二种为矩阵在后。
第一种情况中,平移部分为:m14,m24,m34,第二种情况为m41,m42,m43.
**在内存中存储的时候,数组的小标分别为: 0,1,2,3,4...15 ,其中下标index12,index13,index14为平移部分,这个时候,opengl使用列存贮。
第二种为DirectX使用行主序才能满足要求。这样就有了行主序和列主序的概念。**
OpenGL 列存储的例子:
首先介绍gml里的matrix:
struct mat<4, 4, T, Q>
{
typedef vec<4, T, Q> col_type;
typedef vec<4, T, Q> row_type;
typedef mat<4, 4, T, Q> type;
typedef mat<4, 4, T, Q> transpose_type;
typedef T value_type;
private:
col_type value[4];
}
虽然上面的:col_type value[4];中使用"col_type"有个"col",但其实是vec<4,T,Q>,还是一个数组,即上面的结构体相当于:
struct mat
{
float value[4][4];
}
然后距离看看绕着一个轴选择角度angel的旋转矩阵:
rotation
1 + (1-cos(angle))(xx-1) | -zsin(angle)+(1-cos(angle))x*y | ysin(angle)+(1-cos(angle))x*z |
---|---|---|
zsin(angle)+(1-cos(angle))x*y | 1 + (1-cos(angle))(yy-1) | -xsin(angle)+(1-cos(angle))y*z |
-ysin(angle)+(1-cos(angle))x*z | xsin(angle)+(1-cos(angle))y*z | 1 + (1-cos(angle))(zz-1) |
其在glm中代码:
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate_slow(mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& v)
{
T const a = angle;
T const c = cos(a);
T const s = sin(a);
mat<4, 4, T, Q> Result;
vec<3, T, Q> axis = normalize(v);
Result[0][0] = c + (static_cast<T>(1) - c) * axis.x * axis.x;
Result[0][1] = (static_cast<T>(1) - c) * axis.x * axis.y + s * axis.z;
Result[0][2] = (static_cast<T>(1) - c) * axis.x * axis.z - s * axis.y;
Result[0][3] = static_cast<T>(0);
//上面主要三行存储的时候上面表格中的前三列 [细细品味]
Result[1][0] = (static_cast<T>(1) - c) * axis.y * axis.x - s * axis.z;
Result[1][1] = c + (static_cast<T>(1) - c) * axis.y * axis.y;
Result[1][2] = (static_cast<T>(1) - c) * axis.y * axis.z + s * axis.x;
Result[1][3] = static_cast<T>(0);
Result[2][0] = (static_cast<T>(1) - c) * axis.z * axis.x + s * axis.y;
Result[2][1] = (static_cast<T>(1) - c) * axis.z * axis.y - s * axis.x;
Result[2][2] = c + (static_cast<T>(1) - c) * axis.z * axis.z;
Result[2][3] = static_cast<T>(0);
Result[3] = vec<4, T, Q>(0, 0, 0, 1);
return m * Result;
}
GLSL 4×4 Matrix Fields
Here is a short article about manipulating GLSL mat4 fields. In C, an OpenGL 4×4 matrix is a 16-float array:
float c_matrix[16];
In GLSL the same matrix is:
mat4 glsl_matrix;
Let’s see how to map the C matrix to the GLSL one and vice-versa. Matrices in OpenGL are column-major. The c_matrix[] can be represented by:
The first column is made up of entries 0, 1, 2 and 3. The second column is 4, 5, 6, 7 and so on.
In C, the first entry of the first column is:
c_matrix[0];
While the second entry of the third column is:
c_matrix[9];
Now in GLSL. The first entry of the first column is:
glsl_matrix[0][0];
The second entry of the third column is:
glsl_matrix[2][1];
A mat4 can be seen as four vec4 vectors:
vec4 c0 = glsl_matrix[0].xyzw;
vec4 c1 = glsl_matrix[1].xyzw;
vec4 c2 = glsl_matrix[2].xyzw;
vec4 c3 = glsl_matrix[3].xyzw;
The first entry of the first column is now:
glsl_matrix[0].x;
And the second entry of the third column is:
glsl_matrix[2].x;
posted on 2023-09-28 11:08 Ultraman_X 阅读(3) 评论(0) 编辑 收藏 举报