OpenGL变换矩阵计算函数

 1 #include <cmath> // 用于数学运算
 2 
 3 // 3D向量结构体(用于表示坐标、方向等)
 4 struct vec3 {
 5     float x, y, z;
 6 
 7     vec3 operator-(const vec3& other) const {
 8         return {x - other.x, y - other.y, z - other.z};
 9     }
10 
11     // 向量叉乘
12     vec3 cross(const vec3& other) const {
13         return {
14             y * other.z - z * other.y,
15             z * other.x - x * other.z,
16             x * other.y - y * other.x
17         };
18     }
19 
20     // 向量点乘
21     float dot(const vec3& other) const {
22         return x * other.x + y * other.y + z * other.z;
23     }
24 
25     // 向量归一化
26     vec3 normalize() const {
27         float len = std::sqrt(x*x + y*y + z*z);
28         return {x/len, y/len, z/len};
29     }
30 };
31 
32 // 计算视图矩阵(View Matrix)
33 void createViewMatrix(vec3 position, vec3 target, vec3 up, float* matrix) {
34     // 1. 计算相机的三个正交轴
35     vec3 forward = (target - position).normalize();  // 相机朝向方向(Z轴负方向)
36     vec3 right = up.cross(forward).normalize();     // 右轴(X轴)
37     vec3 up_new = forward.cross(right);             // 上轴(Y轴,已正交)
38 
39     // 2. 计算平移分量(将相机位置转换到新坐标系)
40     float tx = -position.dot(right);
41     float ty = -position.dot(up_new);
42     float tz = position.dot(forward);
43 
44     // 3. 按列主序填充视图矩阵
45     // 第一列:右轴分量
46     matrix[0] = right.x;   matrix[1] = right.y;   matrix[2] = right.z;   matrix[3] = 0.0f;
47     // 第二列:上轴分量
48     matrix[4] = up_new.x;  matrix[5] = up_new.y;  matrix[6] = up_new.z;  matrix[7] = 0.0f;
49     // 第三列:反向朝向轴分量
50     matrix[8] = -forward.x; matrix[9] = -forward.y; matrix[10] = -forward.z; matrix[11] = 0.0f;
51     // 第四列:平移分量
52     matrix[12] = tx;       matrix[13] = ty;       matrix[14] = tz;       matrix[15] = 1.0f;
53 }
54 
55 // 计算透视投影矩阵(Perspective Projection)
56 void createPerspectiveProjectionMatrix(float fovY, float aspect, float near, float far, float* matrix) {
57     const float PI = 3.14159265358979323846f;
58     float f = 1.0f / std::tan(fovY * 0.5f * PI / 180.0f); // 焦距
59 
60     // 列主序填充矩阵
61     matrix[0] = f / aspect;  matrix[1] = 0.0f; matrix[2] = 0.0f;                        matrix[3] = 0.0f;
62     matrix[4] = 0.0f;        matrix[5] = f;     matrix[6] = 0.0f;                        matrix[7] = 0.0f;
63     matrix[8] = 0.0f;        matrix[9] = 0.0f; matrix[10] = (far + near) / (near - far); matrix[11] = -1.0f;
64     matrix[12] = 0.0f;       matrix[13] = 0.0f; matrix[14] = (2 * far * near) / (near - far); matrix[15] = 0.0f;
65 }
66 
67 // 计算正交投影矩阵(Orthographic Projection)
68 void createOrthoProjectionMatrix(float left, float right, float bottom, float top, float near, float far, float* matrix) {
69     // 计算缩放和平移因子
70     float r_l = right - left;
71     float t_b = top - bottom;
72     float f_n = far - near;
73 
74     // 列主序填充矩阵
75     matrix[0] = 2.0f / r_l;  
76     matrix[1] = 0.0f;     
77     matrix[2] = 0.0f;          
78     matrix[3] = 0.0f;
79     matrix[4] = 0.0f;        
80     matrix[5] = 2.0f / t_b; 
81     matrix[6] = 0.0f;          
82     matrix[7] = 0.0f;
83     matrix[8] = 0.0f;        
84     matrix[9] = 0.0f;     
85     matrix[10] = -2.0f / f_n;  
86     matrix[11] = 0.0f;
87     matrix[12] = -(right + left) / r_l;
88     matrix[13] = -(top + bottom) / t_b;
89     matrix[14] = -(far + near) / f_n;
90     matrix[15] = 1.0f;
91 }

 

posted @ 2025-04-07 17:40  禅元天道  阅读(20)  评论(0)    收藏  举报