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编辑  收藏  举报

导航