version 2.8
matrix.c
1 #include "zgl.h"
2 
3 void gl_print_matrix( const float *m)
4 {
5 #ifndef NO_CLIBRARY
6  int i;
7 
8  for (i=0;i<4;i++) {
9  fprintf(stderr,"%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] );
10  }
11 #else
12  (void) m;
13 #endif
14 }
15 
16 static inline void gl_matrix_update(GLContext *c)
17 {
18  c->matrix_model_projection_updated=(c->matrix_mode<=1);
19 }
20 
21 
22 void glopMatrixMode(GLContext *c,GLParam *p)
23 {
24  int mode=p[1].i;
25  switch(mode) {
26  case GL_MODELVIEW:
27  c->matrix_mode=0;
28  break;
29  case GL_PROJECTION:
30  c->matrix_mode=1;
31  break;
32  case GL_TEXTURE:
33  c->matrix_mode=2;
34  break;
35  default:
36  gl_assert(0);
37  }
38 }
39 
40 void glopLoadMatrix(GLContext *c,GLParam *p)
41 {
42  M4 *m;
43  int i;
44 
45  GLParam *q;
46 
47  m=c->matrix_stack_ptr[c->matrix_mode];
48  q=p+1;
49 
50  for(i=0;i<4;i++) {
51  m->m[0][i]=q[0].f;
52  m->m[1][i]=q[1].f;
53  m->m[2][i]=q[2].f;
54  m->m[3][i]=q[3].f;
55  q+=4;
56  }
57 
58  gl_matrix_update(c);
59 }
60 
61 void glopLoadIdentity(GLContext *c,GLParam *p)
62 {
63  (void)p;
64  gl_M4_Id(c->matrix_stack_ptr[c->matrix_mode]);
65 
66  gl_matrix_update(c);
67 }
68 
69 void glopMultMatrix(GLContext *c,GLParam *p)
70 {
71  M4 m;
72  int i;
73 
74  GLParam *q;
75  q=p+1;
76 
77  for(i=0;i<4;i++) {
78  m.m[0][i]=q[0].f;
79  m.m[1][i]=q[1].f;
80  m.m[2][i]=q[2].f;
81  m.m[3][i]=q[3].f;
82  q+=4;
83  }
84 
85  gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode],&m);
86 
87  gl_matrix_update(c);
88 }
89 
90 
91 void glopPushMatrix(GLContext *c,GLParam *p)
92 {
93  int n=c->matrix_mode;
94  M4 *m;
95  (void)p;
96 
97  gl_assert( (c->matrix_stack_ptr[n] - c->matrix_stack[n] + 1 )
98  < c->matrix_stack_depth_max[n] );
99 
100  m=++c->matrix_stack_ptr[n];
101 
102  gl_M4_Move(&m[0],&m[-1]);
103 
104  gl_matrix_update(c);
105 }
106 
107 void glopPopMatrix(GLContext *c,GLParam *p)
108 {
109  int n=c->matrix_mode;
110  (void)p;
111 
112  gl_assert( c->matrix_stack_ptr[n] > c->matrix_stack[n] );
113  c->matrix_stack_ptr[n]--;
114  gl_matrix_update(c);
115 }
116 
117 
118 void glopRotate(GLContext *c,GLParam *p)
119 {
120  M4 m;
121  float u[3];
122  float angle;
123  int dir_code;
124 
125  angle = p[1].f * M_PI / 180.0;
126  u[0]=p[2].f;
127  u[1]=p[3].f;
128  u[2]=p[4].f;
129 
130  /* simple case detection */
131  dir_code = ((u[0] != 0)<<2) | ((u[1] != 0)<<1) | (u[2] != 0);
132 
133  switch(dir_code) {
134  case 0:
135  gl_M4_Id(&m);
136  break;
137  case 4:
138  if (u[0] < 0) angle=-angle;
139  gl_M4_Rotate(&m,angle,0);
140  break;
141  case 2:
142  if (u[1] < 0) angle=-angle;
143  gl_M4_Rotate(&m,angle,1);
144  break;
145  case 1:
146  if (u[2] < 0) angle=-angle;
147  gl_M4_Rotate(&m,angle,2);
148  break;
149  default:
150  {
151  float cost, sint;
152 
153  /* normalize vector */
154  float len = u[0]*u[0]+u[1]*u[1]+u[2]*u[2];
155  if (len == 0.0f) return;
156  len = 1.0f / sqrt(len);
157  u[0] *= len;
158  u[1] *= len;
159  u[2] *= len;
160 
161  /* store cos and sin values */
162  cost=cos(angle);
163  sint=sin(angle);
164 
165  /* fill in the values */
166  m.m[3][0]=m.m[3][1]=m.m[3][2]=
167  m.m[0][3]=m.m[1][3]=m.m[2][3]=0.0f;
168  m.m[3][3]=1.0f;
169 
170  /* do the math */
171  m.m[0][0]=u[0]*u[0]+cost*(1-u[0]*u[0]);
172  m.m[1][0]=u[0]*u[1]*(1-cost)-u[2]*sint;
173  m.m[2][0]=u[2]*u[0]*(1-cost)+u[1]*sint;
174  m.m[0][1]=u[0]*u[1]*(1-cost)+u[2]*sint;
175  m.m[1][1]=u[1]*u[1]+cost*(1-u[1]*u[1]);
176  m.m[2][1]=u[1]*u[2]*(1-cost)-u[0]*sint;
177  m.m[0][2]=u[2]*u[0]*(1-cost)-u[1]*sint;
178  m.m[1][2]=u[1]*u[2]*(1-cost)+u[0]*sint;
179  m.m[2][2]=u[2]*u[2]+cost*(1-u[2]*u[2]);
180  }
181  }
182 
183  gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode],&m);
184 
185  gl_matrix_update(c);
186 }
187 
188 void glopScale(GLContext *c,GLParam *p)
189 {
190  float *m;
191  float x=p[1].f,y=p[2].f,z=p[3].f;
192 
193  m=&c->matrix_stack_ptr[c->matrix_mode]->m[0][0];
194 
195  m[0] *= x; m[1] *= y; m[2] *= z;
196  m[4] *= x; m[5] *= y; m[6] *= z;
197  m[8] *= x; m[9] *= y; m[10] *= z;
198  m[12] *= x; m[13] *= y; m[14] *= z;
199  gl_matrix_update(c);
200 }
201 
202 void glopTranslate(GLContext *c,GLParam *p)
203 {
204  float *m;
205  float x=p[1].f,y=p[2].f,z=p[3].f;
206 
207  m=&c->matrix_stack_ptr[c->matrix_mode]->m[0][0];
208 
209  m[3] = m[0] * x + m[1] * y + m[2] * z + m[3];
210  m[7] = m[4] * x + m[5] * y + m[6] * z + m[7];
211  m[11] = m[8] * x + m[9] * y + m[10] * z + m[11];
212  m[15] = m[12] * x + m[13] * y + m[14] * z + m[15];
213 
214  gl_matrix_update(c);
215 }
216 
217 
218 void glopFrustum(GLContext *c,GLParam *p)
219 {
220  float *r;
221  M4 m;
222  float left=p[1].f;
223  float right=p[2].f;
224  float bottom=p[3].f;
225  float top=p[4].f;
226  float xnear=p[5].f;
227  float farp=p[6].f;
228  float x,y,A,B,C,D;
229 
230  x = (2.0*xnear) / (right-left);
231  y = (2.0*xnear) / (top-bottom);
232  A = (right+left) / (right-left);
233  B = (top+bottom) / (top-bottom);
234  C = -(farp+xnear) / ( farp-xnear);
235  D = -(2.0*farp*xnear) / (farp-xnear);
236 
237  r=&m.m[0][0];
238  r[0]= x; r[1]=0; r[2]=A; r[3]=0;
239  r[4]= 0; r[5]=y; r[6]=B; r[7]=0;
240  r[8]= 0; r[9]=0; r[10]=C; r[11]=D;
241  r[12]= 0; r[13]=0; r[14]=-1; r[15]=0;
242 
243  gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode],&m);
244 
245  gl_matrix_update(c);
246 }
247