2 #define _USE_MATH_DEFINES
\r
4 #include "glmatrix.h"
\r
6 #define MMODE_IDX(x) ((x) - GL_MODELVIEW)
\r
7 #define MAT_STACK_SIZE 32
\r
8 #define MAT_IDENT {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}
\r
10 static int mm_idx = 0;
\r
11 static float mat_stack[3][MAT_STACK_SIZE][16] = {{MAT_IDENT}, {MAT_IDENT}, {MAT_IDENT}};
\r
12 static int stack_top[3];
\r
14 void gl_matrix_mode(int mm)
\r
16 mm_idx = MMODE_IDX(mm);
\r
19 void gl_push_matrix(void)
\r
21 int top = stack_top[mm_idx];
\r
23 memcpy(mat_stack[mm_idx][top + 1], mat_stack[mm_idx][top], 16 * sizeof(float));
\r
24 stack_top[mm_idx]++;
\r
27 void gl_pop_matrix(void)
\r
29 stack_top[mm_idx]--;
\r
32 void gl_load_identity(void)
\r
34 static const float idmat[] = MAT_IDENT;
\r
35 int top = stack_top[mm_idx];
\r
36 float *mat = mat_stack[mm_idx][top];
\r
38 memcpy(mat, idmat, sizeof idmat);
\r
41 void gl_load_matrixf(const float *m)
\r
43 int top = stack_top[mm_idx];
\r
44 float *mat = mat_stack[mm_idx][top];
\r
46 memcpy(mat, m, 16 * sizeof *mat);
\r
49 #define M4(i, j) ((i << 2) + j)
\r
51 void gl_mult_matrixf(const float *m2)
\r
54 int top = stack_top[mm_idx];
\r
55 float *m1 = mat_stack[mm_idx][top];
\r
58 for(i=0; i<4; i++) {
\r
59 for(j=0; j<4; j++) {
\r
60 res[M4(i,j)] = m1[M4(i,0)] * m2[M4(0,j)] +
\r
61 m1[M4(i,1)] * m2[M4(1,j)] +
\r
62 m1[M4(i,2)] * m2[M4(2,j)] +
\r
63 m1[M4(i,3)] * m2[M4(3,j)];
\r
67 memcpy(m1, res, sizeof res);
\r
70 void gl_translatef(float x, float y, float z)
\r
72 float mat[] = MAT_IDENT;
\r
78 gl_mult_matrixf(mat);
\r
81 void gl_rotatef(float angle, float x, float y, float z)
\r
83 float mat[] = MAT_IDENT;
\r
85 float angle_rad = (float)M_PI * angle / 180.f;
\r
86 float sina = (float)sin(angle_rad);
\r
87 float cosa = (float)cos(angle_rad);
\r
88 float one_minus_cosa = 1.f - cosa;
\r
93 mat[0] = nxsq + (1.f - nxsq) * cosa;
\r
94 mat[4] = x * y * one_minus_cosa - z * sina;
\r
95 mat[8] = x * z * one_minus_cosa + y * sina;
\r
96 mat[1] = x * y * one_minus_cosa + z * sina;
\r
97 mat[5] = nysq + (1.f - nysq) * cosa;
\r
98 mat[9] = y * z * one_minus_cosa - x * sina;
\r
99 mat[2] = x * z * one_minus_cosa - y * sina;
\r
100 mat[6] = y * z * one_minus_cosa + x * sina;
\r
101 mat[10] = nzsq + (1.f - nzsq) * cosa;
\r
103 gl_mult_matrixf(mat);
\r
106 void gl_scalef(float x, float y, float z)
\r
108 float mat[] = MAT_IDENT;
\r
114 gl_mult_matrixf(mat);
\r
117 void gl_ortho(float left, float right, float bottom, float top, float near, float far)
\r
119 float mat[] = MAT_IDENT;
\r
121 float dx = right - left;
\r
122 float dy = top - bottom;
\r
123 float dz = far - near;
\r
125 float tx = -(right + left) / dx;
\r
126 float ty = -(top + bottom) / dy;
\r
127 float tz = -(far + near) / dz;
\r
129 float sx = 2.f / dx;
\r
130 float sy = 2.f / dy;
\r
131 float sz = -2.f / dz;
\r
140 gl_mult_matrixf(mat);
\r
143 void gl_frustum(float left, float right, float bottom, float top, float near, float far)
\r
145 float mat[] = MAT_IDENT;
\r
147 float dx = right - left;
\r
148 float dy = top - bottom;
\r
149 float dz = far - near;
\r
151 float a = (right + left) / dx;
\r
152 float b = (top + bottom) / dy;
\r
153 float c = -(far + near) / dz;
\r
154 float d = -2.f * far * near / dz;
\r
156 mat[0] = 2.f * near / dx;
\r
157 mat[5] = 2.f * near / dy;
\r
164 gl_mult_matrixf(mat);
\r
167 void glu_perspective(float vfov, float aspect, float near, float far)
\r
169 float vfov_rad = (float)M_PI * vfov / 180.f;
\r
170 float x = near * (float)tan(vfov_rad / 2.f);
\r
171 gl_frustum(-aspect * x, aspect * x, -x, x, near, far);
\r
174 /* return the matrix (16 elements, 4x4 matrix, row-major order */
\r
175 float* get_matrix(int mm)
\r
177 int idx = MMODE_IDX(mm);
\r
178 int top = stack_top[idx];
\r
179 return mat_stack[idx][top];
\r
183 #define M3(i, j) ((i * 3) + j)
\r
184 static float inv_transpose_result[9];
\r
186 /* return the inverse transpose of the left-upper 3x3 of a matrix
\r
187 The returned pointer is only valid until the next time this function is
\r
188 called, so make a deep copy when you want to keep it around.
\r
190 float* get_inv_transpose_3x3(int mm)
\r
192 int idx = MMODE_IDX(mm);
\r
193 int top = stack_top[idx];
\r
194 float *m1 = mat_stack[idx][top];
\r
197 float determinant = +m1[M4(0,0)]*(m1[M4(1,1)]*m1[M4(2,2)]-m1[M4(2,1)]*m1[M4(1,2)])
\r
198 -m1[M4(0,1)]*(m1[M4(1,0)]*m1[M4(2,2)]-m1[M4(1,2)]*m1[M4(2,0)])
\r
199 +m1[M4(0,2)]*(m1[M4(1,0)]*m1[M4(2,1)]-m1[M4(1,1)]*m1[M4(2,0)]);
\r
201 float invdet = 1/determinant;
\r
203 inv_transpose_result[M3(0,0)] = (m1[M4(1,1)]*m1[M4(2,2)]-m1[M4(2,1)]*m1[M4(1,2)])*invdet;
\r
204 inv_transpose_result[M3(1,0)] = -(m1[M4(0,1)]*m1[M4(2,2)]-m1[M4(0,2)]*m1[M4(2,1)])*invdet;
\r
205 inv_transpose_result[M3(2,0)] = (m1[M4(0,1)]*m1[M4(1,2)]-m1[M4(0,2)]*m1[M4(1,1)])*invdet;
\r
206 inv_transpose_result[M3(0,1)] = -(m1[M4(1,0)]*m1[M4(2,2)]-m1[M4(1,2)]*m1[M4(2,0)])*invdet;
\r
207 inv_transpose_result[M3(1,1)] = (m1[M4(0,0)]*m1[M4(2,2)]-m1[M4(0,2)]*m1[M4(2,0)])*invdet;
\r
208 inv_transpose_result[M3(2,1)] = -(m1[M4(0,0)]*m1[M4(1,2)]-m1[M4(1,0)]*m1[M4(0,2)])*invdet;
\r
209 inv_transpose_result[M3(0,2)] = (m1[M4(1,0)]*m1[M4(2,1)]-m1[M4(2,0)]*m1[M4(1,1)])*invdet;
\r
210 inv_transpose_result[M3(1,2)] = -(m1[M4(0,0)]*m1[M4(2,1)]-m1[M4(2,0)]*m1[M4(0,1)])*invdet;
\r
211 inv_transpose_result[M3(2,2)] = (m1[M4(0,0)]*m1[M4(1,1)]-m1[M4(1,0)]*m1[M4(0,1)])*invdet;
\r
213 return inv_transpose_result;
\r