ReactOS  0.4.14-dev-41-g31d7680
matrix.c
Go to the documentation of this file.
1 /* $Id: matrix.c,v 1.23 1997/12/29 23:48:53 brianp Exp $ */
2 
3 /*
4  * Mesa 3-D graphics library
5  * Version: 2.6
6  * Copyright (C) 1995-1997 Brian Paul
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 
24 /*
25  * $Log: matrix.c,v $
26  * Revision 1.23 1997/12/29 23:48:53 brianp
27  * call Driver.NearFar() in gl_LoadMatrixf() for projection matrix
28  *
29  * Revision 1.22 1997/10/16 23:37:23 brianp
30  * fixed scotter's email address
31  *
32  * Revision 1.21 1997/08/13 01:54:34 brianp
33  * new matrix invert code from Scott McCaskill
34  *
35  * Revision 1.20 1997/07/24 01:23:16 brianp
36  * changed precompiled header symbol from PCH to PC_HEADER
37  *
38  * Revision 1.19 1997/05/30 02:21:43 brianp
39  * gl_PopMatrix() set ctx->New*Matrix flag incorrectly
40  *
41  * Revision 1.18 1997/05/28 04:06:03 brianp
42  * implemented projection near/far value stack for Driver.NearFar() function
43  *
44  * Revision 1.17 1997/05/28 03:25:43 brianp
45  * added precompiled header (PCH) support
46  *
47  * Revision 1.16 1997/05/01 01:39:40 brianp
48  * replace sqrt() with GL_SQRT()
49  *
50  * Revision 1.15 1997/04/21 01:20:41 brianp
51  * added MATRIX_2D_NO_ROT
52  *
53  * Revision 1.14 1997/04/20 20:28:49 brianp
54  * replaced abort() with gl_problem()
55  *
56  * Revision 1.13 1997/04/20 16:31:08 brianp
57  * added NearFar device driver function
58  *
59  * Revision 1.12 1997/04/20 16:18:15 brianp
60  * added glOrtho and glFrustum API pointers
61  *
62  * Revision 1.11 1997/04/01 04:23:53 brianp
63  * added gl_analyze_*_matrix() functions
64  *
65  * Revision 1.10 1997/02/10 19:47:53 brianp
66  * moved buffer resize code out of gl_Viewport() into gl_ResizeBuffersMESA()
67  *
68  * Revision 1.9 1997/01/31 23:32:40 brianp
69  * now clear depth buffer after reallocation due to window resize
70  *
71  * Revision 1.8 1997/01/29 19:06:04 brianp
72  * removed extra, local definition of Identity[] matrix
73  *
74  * Revision 1.7 1997/01/28 22:19:17 brianp
75  * new matrix inversion code from Stephane Rehel
76  *
77  * Revision 1.6 1996/12/22 17:53:11 brianp
78  * faster invert_matrix() function from scotter@iname.com
79  *
80  * Revision 1.5 1996/12/02 18:58:34 brianp
81  * gl_rotation_matrix() now returns identity matrix if given a 0 rotation axis
82  *
83  * Revision 1.4 1996/09/27 01:29:05 brianp
84  * added missing default cases to switches
85  *
86  * Revision 1.3 1996/09/15 14:18:37 brianp
87  * now use GLframebuffer and GLvisual
88  *
89  * Revision 1.2 1996/09/14 06:46:04 brianp
90  * better matmul() from Jacques Leroy
91  *
92  * Revision 1.1 1996/09/13 01:38:16 brianp
93  * Initial revision
94  *
95  */
96 
97 
98 /*
99  * Matrix operations
100  *
101  *
102  * NOTES:
103  * 1. 4x4 transformation matrices are stored in memory in column major order.
104  * 2. Points/vertices are to be thought of as column vectors.
105  * 3. Transformation of a point p by a matrix M is: p' = M * p
106  *
107  */
108 
109 
110 #ifdef PC_HEADER
111 #include "all.h"
112 #else
113 #include <math.h>
114 #include <stdio.h>
115 #include <stdlib.h>
116 #include <string.h>
117 #include "context.h"
118 #include "dlist.h"
119 #include "macros.h"
120 #include "matrix.h"
121 #include "mmath.h"
122 #include "types.h"
123 #endif
124 
125 
126 
127 static GLfloat Identity[16] = {
128  1.0, 0.0, 0.0, 0.0,
129  0.0, 1.0, 0.0, 0.0,
130  0.0, 0.0, 1.0, 0.0,
131  0.0, 0.0, 0.0, 1.0
132 };
133 
134 
135 #if 0
136 static void print_matrix( const GLfloat m[16] )
137 {
138  int i;
139 
140  for (i=0;i<4;i++) {
141  printf("%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] );
142  }
143 }
144 #endif
145 
146 
147 /*
148  * Perform a 4x4 matrix multiplication (product = a x b).
149  * Input: a, b - matrices to multiply
150  * Output: product - product of a and b
151  * WARNING: (product != b) assumed
152  * NOTE: (product == a) allowed
153  */
154 static void matmul( GLfloat *product, const GLfloat *a, const GLfloat *b )
155 {
156  /* This matmul was contributed by Thomas Malik */
157  GLint i;
158 
159 #define A(row,col) a[(col<<2)+row]
160 #define B(row,col) b[(col<<2)+row]
161 #define P(row,col) product[(col<<2)+row]
162 
163  /* i-te Zeile */
164  for (i = 0; i < 4; i++) {
165  GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
166  P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
167  P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
168  P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
169  P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
170  }
171 
172 #undef A
173 #undef B
174 #undef P
175 }
176 
177 
178 
179 /*
180  * Compute the inverse of a 4x4 matrix.
181  *
182  * From an algorithm by V. Strassen, 1969, _Numerishe Mathematik_, vol. 13,
183  * pp. 354-356.
184  * 60 multiplies, 24 additions, 10 subtractions, 8 negations, 2 divisions,
185  * 48 assignments, _0_ branches
186  *
187  * This implementation by Scott McCaskill
188  */
189 
190 typedef GLfloat Mat2[2][2];
191 
192 enum {
193  M00 = 0, M01 = 4, M02 = 8, M03 = 12,
194  M10 = 1, M11 = 5, M12 = 9, M13 = 13,
195  M20 = 2, M21 = 6, M22 = 10,M23 = 14,
196  M30 = 3, M31 = 7, M32 = 11,M33 = 15
197 };
198 
199 static void invert_matrix_general( const GLfloat *m, GLfloat *out )
200 {
201  Mat2 r1, r2, r3, r4, r5, r6, r7;
202  const GLfloat * A = m;
203  GLfloat * C = out;
204  GLfloat one_over_det;
205 
206  /*
207  * A is the 4x4 source matrix (to be inverted).
208  * C is the 4x4 destination matrix
209  * a11 is the 2x2 matrix in the upper left quadrant of A
210  * a12 is the 2x2 matrix in the upper right quadrant of A
211  * a21 is the 2x2 matrix in the lower left quadrant of A
212  * a22 is the 2x2 matrix in the lower right quadrant of A
213  * similarly, cXX are the 2x2 quadrants of the destination matrix
214  */
215 
216  /* R1 = inverse( a11 ) */
217  one_over_det = 1.0f / ( ( A[M00] * A[M11] ) - ( A[M10] * A[M01] ) );
218  r1[0][0] = one_over_det * A[M11];
219  r1[0][1] = one_over_det * -A[M01];
220  r1[1][0] = one_over_det * -A[M10];
221  r1[1][1] = one_over_det * A[M00];
222 
223  /* R2 = a21 x R1 */
224  r2[0][0] = A[M20] * r1[0][0] + A[M21] * r1[1][0];
225  r2[0][1] = A[M20] * r1[0][1] + A[M21] * r1[1][1];
226  r2[1][0] = A[M30] * r1[0][0] + A[M31] * r1[1][0];
227  r2[1][1] = A[M30] * r1[0][1] + A[M31] * r1[1][1];
228 
229  /* R3 = R1 x a12 */
230  r3[0][0] = r1[0][0] * A[M02] + r1[0][1] * A[M12];
231  r3[0][1] = r1[0][0] * A[M03] + r1[0][1] * A[M13];
232  r3[1][0] = r1[1][0] * A[M02] + r1[1][1] * A[M12];
233  r3[1][1] = r1[1][0] * A[M03] + r1[1][1] * A[M13];
234 
235  /* R4 = a21 x R3 */
236  r4[0][0] = A[M20] * r3[0][0] + A[M21] * r3[1][0];
237  r4[0][1] = A[M20] * r3[0][1] + A[M21] * r3[1][1];
238  r4[1][0] = A[M30] * r3[0][0] + A[M31] * r3[1][0];
239  r4[1][1] = A[M30] * r3[0][1] + A[M31] * r3[1][1];
240 
241  /* R5 = R4 - a22 */
242  r5[0][0] = r4[0][0] - A[M22];
243  r5[0][1] = r4[0][1] - A[M23];
244  r5[1][0] = r4[1][0] - A[M32];
245  r5[1][1] = r4[1][1] - A[M33];
246 
247  /* R6 = inverse( R5 ) */
248  one_over_det = 1.0f / ( ( r5[0][0] * r5[1][1] ) - ( r5[1][0] * r5[0][1] ) );
249  r6[0][0] = one_over_det * r5[1][1];
250  r6[0][1] = one_over_det * -r5[0][1];
251  r6[1][0] = one_over_det * -r5[1][0];
252  r6[1][1] = one_over_det * r5[0][0];
253 
254  /* c12 = R3 x R6 */
255  C[M02] = r3[0][0] * r6[0][0] + r3[0][1] * r6[1][0];
256  C[M03] = r3[0][0] * r6[0][1] + r3[0][1] * r6[1][1];
257  C[M12] = r3[1][0] * r6[0][0] + r3[1][1] * r6[1][0];
258  C[M13] = r3[1][0] * r6[0][1] + r3[1][1] * r6[1][1];
259 
260  /* c21 = R6 x R2 */
261  C[M20] = r6[0][0] * r2[0][0] + r6[0][1] * r2[1][0];
262  C[M21] = r6[0][0] * r2[0][1] + r6[0][1] * r2[1][1];
263  C[M30] = r6[1][0] * r2[0][0] + r6[1][1] * r2[1][0];
264  C[M31] = r6[1][0] * r2[0][1] + r6[1][1] * r2[1][1];
265 
266  /* R7 = R3 x c21 */
267  r7[0][0] = r3[0][0] * C[M20] + r3[0][1] * C[M30];
268  r7[0][1] = r3[0][0] * C[M21] + r3[0][1] * C[M31];
269  r7[1][0] = r3[1][0] * C[M20] + r3[1][1] * C[M30];
270  r7[1][1] = r3[1][0] * C[M21] + r3[1][1] * C[M31];
271 
272  /* c11 = R1 - R7 */
273  C[M00] = r1[0][0] - r7[0][0];
274  C[M01] = r1[0][1] - r7[0][1];
275  C[M10] = r1[1][0] - r7[1][0];
276  C[M11] = r1[1][1] - r7[1][1];
277 
278  /* c22 = -R6 */
279  C[M22] = -r6[0][0];
280  C[M23] = -r6[0][1];
281  C[M32] = -r6[1][0];
282  C[M33] = -r6[1][1];
283 }
284 
285 
286 /*
287  * Invert matrix m. This algorithm contributed by Stephane Rehel
288  * <rehel@worldnet.fr>
289  */
290 static void invert_matrix( const GLfloat *m, GLfloat *out )
291 {
292 /* NB. OpenGL Matrices are COLUMN major. */
293 #define MAT(m,r,c) (m)[(c)*4+(r)]
294 
295 /* Here's some shorthand converting standard (row,column) to index. */
296 #define m11 MAT(m,0,0)
297 #define m12 MAT(m,0,1)
298 #define m13 MAT(m,0,2)
299 #define m14 MAT(m,0,3)
300 #define m21 MAT(m,1,0)
301 #define m22 MAT(m,1,1)
302 #define m23 MAT(m,1,2)
303 #define m24 MAT(m,1,3)
304 #define m31 MAT(m,2,0)
305 #define m32 MAT(m,2,1)
306 #define m33 MAT(m,2,2)
307 #define m34 MAT(m,2,3)
308 #define m41 MAT(m,3,0)
309 #define m42 MAT(m,3,1)
310 #define m43 MAT(m,3,2)
311 #define m44 MAT(m,3,3)
312 
313  register GLfloat det;
314  GLfloat tmp[16]; /* Allow out == in. */
315 
316  if( m41 != 0. || m42 != 0. || m43 != 0. || m44 != 1. ) {
318  return;
319  }
320 
321  /* Inverse = adjoint / det. (See linear algebra texts.)*/
322 
323  tmp[0]= m22 * m33 - m23 * m32;
324  tmp[1]= m23 * m31 - m21 * m33;
325  tmp[2]= m21 * m32 - m22 * m31;
326 
327  /* Compute determinant as early as possible using these cofactors. */
328  det= m11 * tmp[0] + m12 * tmp[1] + m13 * tmp[2];
329 
330  /* Run singularity test. */
331  if (det == 0.0F) {
332  /* printf("invert_matrix: Warning: Singular matrix.\n"); */
333  MEMCPY( out, Identity, 16*sizeof(GLfloat) );
334  }
335  else {
336  GLfloat d12, d13, d23, d24, d34, d41;
337  register GLfloat im11, im12, im13, im14;
338 
339  det= 1. / det;
340 
341  /* Compute rest of inverse. */
342  tmp[0] *= det;
343  tmp[1] *= det;
344  tmp[2] *= det;
345  tmp[3] = 0.;
346 
347  im11= m11 * det;
348  im12= m12 * det;
349  im13= m13 * det;
350  im14= m14 * det;
351  tmp[4] = im13 * m32 - im12 * m33;
352  tmp[5] = im11 * m33 - im13 * m31;
353  tmp[6] = im12 * m31 - im11 * m32;
354  tmp[7] = 0.;
355 
356  /* Pre-compute 2x2 dets for first two rows when computing */
357  /* cofactors of last two rows. */
358  d12 = im11*m22 - m21*im12;
359  d13 = im11*m23 - m21*im13;
360  d23 = im12*m23 - m22*im13;
361  d24 = im12*m24 - m22*im14;
362  d34 = im13*m24 - m23*im14;
363  d41 = im14*m21 - m24*im11;
364 
365  tmp[8] = d23;
366  tmp[9] = -d13;
367  tmp[10] = d12;
368  tmp[11] = 0.;
369 
370  tmp[12] = -(m32 * d34 - m33 * d24 + m34 * d23);
371  tmp[13] = (m31 * d34 + m33 * d41 + m34 * d13);
372  tmp[14] = -(m31 * d24 + m32 * d41 + m34 * d12);
373  tmp[15] = 1.;
374 
375  MEMCPY(out, tmp, 16*sizeof(GLfloat));
376  }
377 
378 #undef m11
379 #undef m12
380 #undef m13
381 #undef m14
382 #undef m21
383 #undef m22
384 #undef m23
385 #undef m24
386 #undef m31
387 #undef m32
388 #undef m33
389 #undef m34
390 #undef m41
391 #undef m42
392 #undef m43
393 #undef m44
394 #undef MAT
395 }
396 
397 
398 
399 /*
400  * Determine if the given matrix is the identity matrix.
401  */
402 static GLboolean is_identity( const GLfloat m[16] )
403 {
404  if ( m[0]==1.0F && m[4]==0.0F && m[ 8]==0.0F && m[12]==0.0F
405  && m[1]==0.0F && m[5]==1.0F && m[ 9]==0.0F && m[13]==0.0F
406  && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F
407  && m[3]==0.0F && m[7]==0.0F && m[11]==0.0F && m[15]==1.0F) {
408  return GL_TRUE;
409  }
410  else {
411  return GL_FALSE;
412  }
413 }
414 
415 
416 /*
417  * Examine the current modelview matrix to determine its type.
418  * Later we use the matrix type to optimize vertex transformations.
419  */
421 {
422  const GLfloat *m = ctx->ModelViewMatrix;
423  if (is_identity(m)) {
425  }
426  else if ( m[4]==0.0F && m[ 8]==0.0F
427  && m[1]==0.0F && m[ 9]==0.0F
428  && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F
429  && m[3]==0.0F && m[7]==0.0F && m[11]==0.0F && m[15]==1.0F) {
431  }
432  else if ( m[ 8]==0.0F
433  && m[ 9]==0.0F
434  && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F
435  && m[3]==0.0F && m[7]==0.0F && m[11]==0.0F && m[15]==1.0F) {
437  }
438  else if (m[3]==0.0F && m[7]==0.0F && m[11]==0.0F && m[15]==1.0F) {
440  }
441  else {
443  }
444 
447 }
448 
449 
450 
451 /*
452  * Examine the current projection matrix to determine its type.
453  * Later we use the matrix type to optimize vertex transformations.
454  */
456 {
457  /* look for common-case ortho and perspective matrices */
458  const GLfloat *m = ctx->ProjectionMatrix;
459  if (is_identity(m)) {
461  }
462  else if ( m[4]==0.0F && m[8] ==0.0F
463  && m[1]==0.0F && m[9] ==0.0F
464  && m[2]==0.0F && m[6]==0.0F
465  && m[3]==0.0F && m[7]==0.0F && m[11]==0.0F && m[15]==1.0F) {
467  }
468  else if ( m[4]==0.0F && m[12]==0.0F
469  && m[1]==0.0F && m[13]==0.0F
470  && m[2]==0.0F && m[6]==0.0F
471  && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) {
473  }
474  else {
476  }
477 
479 }
480 
481 
482 
483 /*
484  * Examine the current texture matrix to determine its type.
485  * Later we use the matrix type to optimize texture coordinate transformations.
486  */
488 {
489  const GLfloat *m = ctx->TextureMatrix;
490  if (is_identity(m)) {
492  }
493  else if ( m[ 8]==0.0F
494  && m[ 9]==0.0F
495  && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F
496  && m[3]==0.0F && m[7]==0.0F && m[11]==0.0F && m[15]==1.0F) {
498  }
499  else if (m[3]==0.0F && m[7]==0.0F && m[11]==0.0F && m[15]==1.0F) {
501  }
502  else {
504  }
505 
506  ctx->NewTextureMatrix = GL_FALSE;
507 }
508 
509 
510 
514  GLdouble nearval, GLdouble farval )
515 {
516  GLfloat x, y, a, b, c, d;
517  GLfloat m[16];
518 
519  if (nearval<=0.0 || farval<=0.0) {
520  gl_error( ctx, GL_INVALID_VALUE, "glFrustum(near or far)" );
521  }
522 
523  x = (2.0*nearval) / (right-left);
524  y = (2.0*nearval) / (top-bottom);
525  a = (right+left) / (right-left);
526  b = (top+bottom) / (top-bottom);
527  c = -(farval+nearval) / ( farval-nearval);
528  d = -(2.0*farval*nearval) / (farval-nearval); /* error? */
529 
530 #define M(row,col) m[col*4+row]
531  M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
532  M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
533  M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
534  M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
535 #undef M
536 
537  gl_MultMatrixf( ctx, m );
538 
539 
540  /* Need to keep a stack of near/far values in case the user push/pops
541  * the projection matrix stack so that we can call Driver.NearFar()
542  * after a pop.
543  */
544  ctx->NearFarStack[ctx->ProjectionStackDepth][0] = nearval;
545  ctx->NearFarStack[ctx->ProjectionStackDepth][1] = farval;
546 
547  if (ctx->Driver.NearFar) {
548  (*ctx->Driver.NearFar)( ctx, nearval, farval );
549  }
550 }
551 
552 
553 void gl_Ortho( GLcontext *ctx,
556  GLdouble nearval, GLdouble farval )
557 {
558  GLfloat x, y, z;
559  GLfloat tx, ty, tz;
560  GLfloat m[16];
561 
562  x = 2.0 / (right-left);
563  y = 2.0 / (top-bottom);
564  z = -2.0 / (farval-nearval);
565  tx = -(right+left) / (right-left);
566  ty = -(top+bottom) / (top-bottom);
567  tz = -(farval+nearval) / (farval-nearval);
568 
569 #define M(row,col) m[col*4+row]
570  M(0,0) = x; M(0,1) = 0.0F; M(0,2) = 0.0F; M(0,3) = tx;
571  M(1,0) = 0.0F; M(1,1) = y; M(1,2) = 0.0F; M(1,3) = ty;
572  M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = z; M(2,3) = tz;
573  M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F;
574 #undef M
575 
576  gl_MultMatrixf( ctx, m );
577 
578  if (ctx->Driver.NearFar) {
579  (*ctx->Driver.NearFar)( ctx, nearval, farval );
580  }
581 }
582 
583 
585 {
586  if (INSIDE_BEGIN_END(ctx)) {
587  gl_error( ctx, GL_INVALID_OPERATION, "glMatrixMode" );
588  return;
589  }
590  switch (mode) {
591  case GL_MODELVIEW:
592  case GL_PROJECTION:
593  case GL_TEXTURE:
594  ctx->Transform.MatrixMode = mode;
595  break;
596  default:
597  gl_error( ctx, GL_INVALID_ENUM, "glMatrixMode" );
598  }
599 }
600 
601 
602 
604 {
605  if (INSIDE_BEGIN_END(ctx)) {
606  gl_error( ctx, GL_INVALID_OPERATION, "glPushMatrix" );
607  return;
608  }
609  switch (ctx->Transform.MatrixMode) {
610  case GL_MODELVIEW:
612  gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix");
613  return;
614  }
616  ctx->ModelViewMatrix,
617  16*sizeof(GLfloat) );
618  ctx->ModelViewStackDepth++;
619  break;
620  case GL_PROJECTION:
622  gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix");
623  return;
624  }
626  ctx->ProjectionMatrix,
627  16*sizeof(GLfloat) );
628  ctx->ProjectionStackDepth++;
629 
630  /* Save near and far projection values */
631  ctx->NearFarStack[ctx->ProjectionStackDepth][0]
632  = ctx->NearFarStack[ctx->ProjectionStackDepth-1][0];
633  ctx->NearFarStack[ctx->ProjectionStackDepth][1]
634  = ctx->NearFarStack[ctx->ProjectionStackDepth-1][1];
635  break;
636  case GL_TEXTURE:
638  gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix");
639  return;
640  }
642  ctx->TextureMatrix,
643  16*sizeof(GLfloat) );
644  ctx->TextureStackDepth++;
645  break;
646  default:
647  gl_problem(ctx, "Bad matrix mode in gl_PushMatrix");
648  }
649 }
650 
651 
652 
654 {
655  if (INSIDE_BEGIN_END(ctx)) {
656  gl_error( ctx, GL_INVALID_OPERATION, "glPopMatrix" );
657  return;
658  }
659  switch (ctx->Transform.MatrixMode) {
660  case GL_MODELVIEW:
661  if (ctx->ModelViewStackDepth==0) {
662  gl_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix");
663  return;
664  }
665  ctx->ModelViewStackDepth--;
666  MEMCPY( ctx->ModelViewMatrix,
668  16*sizeof(GLfloat) );
670  break;
671  case GL_PROJECTION:
672  if (ctx->ProjectionStackDepth==0) {
673  gl_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix");
674  return;
675  }
676  ctx->ProjectionStackDepth--;
677  MEMCPY( ctx->ProjectionMatrix,
679  16*sizeof(GLfloat) );
681 
682  /* Device driver near/far values */
683  {
684  GLfloat nearVal = ctx->NearFarStack[ctx->ProjectionStackDepth][0];
685  GLfloat farVal = ctx->NearFarStack[ctx->ProjectionStackDepth][1];
686  if (ctx->Driver.NearFar) {
687  (*ctx->Driver.NearFar)( ctx, nearVal, farVal );
688  }
689  }
690  break;
691  case GL_TEXTURE:
692  if (ctx->TextureStackDepth==0) {
693  gl_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix");
694  return;
695  }
696  ctx->TextureStackDepth--;
697  MEMCPY( ctx->TextureMatrix,
698  ctx->TextureStack[ctx->TextureStackDepth],
699  16*sizeof(GLfloat) );
700  ctx->NewTextureMatrix = GL_TRUE;
701  break;
702  default:
703  gl_problem(ctx, "Bad matrix mode in gl_PopMatrix");
704  }
705 }
706 
707 
708 
710 {
711  if (INSIDE_BEGIN_END(ctx)) {
712  gl_error( ctx, GL_INVALID_OPERATION, "glLoadIdentity" );
713  return;
714  }
715  switch (ctx->Transform.MatrixMode) {
716  case GL_MODELVIEW:
717  MEMCPY( ctx->ModelViewMatrix, Identity, 16*sizeof(GLfloat) );
718  MEMCPY( ctx->ModelViewInv, Identity, 16*sizeof(GLfloat) );
721  break;
722  case GL_PROJECTION:
723  MEMCPY( ctx->ProjectionMatrix, Identity, 16*sizeof(GLfloat) );
726  break;
727  case GL_TEXTURE:
728  MEMCPY( ctx->TextureMatrix, Identity, 16*sizeof(GLfloat) );
730  ctx->NewTextureMatrix = GL_FALSE;
731  break;
732  default:
733  gl_problem(ctx, "Bad matrix mode in gl_LoadIdentity");
734  }
735 }
736 
737 
738 void gl_LoadMatrixf( GLcontext *ctx, const GLfloat *m )
739 {
740  if (INSIDE_BEGIN_END(ctx)) {
741  gl_error( ctx, GL_INVALID_OPERATION, "glLoadMatrix" );
742  return;
743  }
744  switch (ctx->Transform.MatrixMode) {
745  case GL_MODELVIEW:
746  MEMCPY( ctx->ModelViewMatrix, m, 16*sizeof(GLfloat) );
748  break;
749  case GL_PROJECTION:
750  MEMCPY( ctx->ProjectionMatrix, m, 16*sizeof(GLfloat) );
752  {
753  float n,f,c,d;
754 
755 #define M(row,col) m[col*4+row]
756  c = M(2,2);
757  d = M(2,3);
758 #undef M
759  n = d / (c-1);
760  f = d / (c+1);
761 
762  /* Need to keep a stack of near/far values in case the user
763  * push/pops the projection matrix stack so that we can call
764  * Driver.NearFar() after a pop.
765  */
766  ctx->NearFarStack[ctx->ProjectionStackDepth][0] = n;
767  ctx->NearFarStack[ctx->ProjectionStackDepth][1] = f;
768 
769  if (ctx->Driver.NearFar) {
770  (*ctx->Driver.NearFar)( ctx, n, f );
771  }
772  }
773  break;
774  case GL_TEXTURE:
775  MEMCPY( ctx->TextureMatrix, m, 16*sizeof(GLfloat) );
776  ctx->NewTextureMatrix = GL_TRUE;
777  break;
778  default:
779  gl_problem(ctx, "Bad matrix mode in gl_LoadMatrixf");
780  }
781 }
782 
783 
784 
785 void gl_MultMatrixf( GLcontext *ctx, const GLfloat *m )
786 {
787  if (INSIDE_BEGIN_END(ctx)) {
788  gl_error( ctx, GL_INVALID_OPERATION, "glMultMatrix" );
789  return;
790  }
791  switch (ctx->Transform.MatrixMode) {
792  case GL_MODELVIEW:
793  matmul( ctx->ModelViewMatrix, ctx->ModelViewMatrix, m );
795  break;
796  case GL_PROJECTION:
797  matmul( ctx->ProjectionMatrix, ctx->ProjectionMatrix, m );
799  break;
800  case GL_TEXTURE:
801  matmul( ctx->TextureMatrix, ctx->TextureMatrix, m );
802  ctx->NewTextureMatrix = GL_TRUE;
803  break;
804  default:
805  gl_problem(ctx, "Bad matrix mode in gl_MultMatrixf");
806  }
807 }
808 
809 
810 
811 /*
812  * Generate a 4x4 transformation matrix from glRotate parameters.
813  */
815  GLfloat m[] )
816 {
817  /* This function contributed by Erich Boleyn (erich@uruk.org) */
818  GLfloat mag, s, c;
819  GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
820 
821  s = sin( angle * DEG2RAD );
822  c = cos( angle * DEG2RAD );
823 
824  mag = GL_SQRT( x*x + y*y + z*z );
825 
826  if (mag == 0.0) {
827  /* generate an identity matrix and return */
828  MEMCPY(m, Identity, sizeof(GLfloat)*16);
829  return;
830  }
831 
832  x /= mag;
833  y /= mag;
834  z /= mag;
835 
836 #define M(row,col) m[col*4+row]
837 
838  /*
839  * Arbitrary axis rotation matrix.
840  *
841  * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
842  * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation
843  * (which is about the X-axis), and the two composite transforms
844  * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
845  * from the arbitrary axis to the X-axis then back. They are
846  * all elementary rotations.
847  *
848  * Rz' is a rotation about the Z-axis, to bring the axis vector
849  * into the x-z plane. Then Ry' is applied, rotating about the
850  * Y-axis to bring the axis vector parallel with the X-axis. The
851  * rotation about the X-axis is then performed. Ry and Rz are
852  * simply the respective inverse transforms to bring the arbitrary
853  * axis back to it's original orientation. The first transforms
854  * Rz' and Ry' are considered inverses, since the data from the
855  * arbitrary axis gives you info on how to get to it, not how
856  * to get away from it, and an inverse must be applied.
857  *
858  * The basic calculation used is to recognize that the arbitrary
859  * axis vector (x, y, z), since it is of unit length, actually
860  * represents the sines and cosines of the angles to rotate the
861  * X-axis to the same orientation, with theta being the angle about
862  * Z and phi the angle about Y (in the order described above)
863  * as follows:
864  *
865  * cos ( theta ) = x / sqrt ( 1 - z^2 )
866  * sin ( theta ) = y / sqrt ( 1 - z^2 )
867  *
868  * cos ( phi ) = sqrt ( 1 - z^2 )
869  * sin ( phi ) = z
870  *
871  * Note that cos ( phi ) can further be inserted to the above
872  * formulas:
873  *
874  * cos ( theta ) = x / cos ( phi )
875  * sin ( theta ) = y / sin ( phi )
876  *
877  * ...etc. Because of those relations and the standard trigonometric
878  * relations, it is pssible to reduce the transforms down to what
879  * is used below. It may be that any primary axis chosen will give the
880  * same results (modulo a sign convention) using thie method.
881  *
882  * Particularly nice is to notice that all divisions that might
883  * have caused trouble when parallel to certain planes or
884  * axis go away with care paid to reducing the expressions.
885  * After checking, it does perform correctly under all cases, since
886  * in all the cases of division where the denominator would have
887  * been zero, the numerator would have been zero as well, giving
888  * the expected result.
889  */
890 
891  xx = x * x;
892  yy = y * y;
893  zz = z * z;
894  xy = x * y;
895  yz = y * z;
896  zx = z * x;
897  xs = x * s;
898  ys = y * s;
899  zs = z * s;
900  one_c = 1.0F - c;
901 
902  M(0,0) = (one_c * xx) + c;
903  M(0,1) = (one_c * xy) - zs;
904  M(0,2) = (one_c * zx) + ys;
905  M(0,3) = 0.0F;
906 
907  M(1,0) = (one_c * xy) + zs;
908  M(1,1) = (one_c * yy) + c;
909  M(1,2) = (one_c * yz) - xs;
910  M(1,3) = 0.0F;
911 
912  M(2,0) = (one_c * zx) - ys;
913  M(2,1) = (one_c * yz) + xs;
914  M(2,2) = (one_c * zz) + c;
915  M(2,3) = 0.0F;
916 
917  M(3,0) = 0.0F;
918  M(3,1) = 0.0F;
919  M(3,2) = 0.0F;
920  M(3,3) = 1.0F;
921 
922 #undef M
923 }
924 
925 
926 
929 {
930  GLfloat m[16];
931  gl_rotation_matrix( angle, x, y, z, m );
932  gl_MultMatrixf( ctx, m );
933 }
934 
935 
936 
937 /*
938  * Execute a glScale call
939  */
941 {
942  GLfloat *m;
943 
944  if (INSIDE_BEGIN_END(ctx)) {
945  gl_error( ctx, GL_INVALID_OPERATION, "glScale" );
946  return;
947  }
948  switch (ctx->Transform.MatrixMode) {
949  case GL_MODELVIEW:
950  m = ctx->ModelViewMatrix;
952  break;
953  case GL_PROJECTION:
954  m = ctx->ProjectionMatrix;
956  break;
957  case GL_TEXTURE:
958  m = ctx->TextureMatrix;
959  ctx->NewTextureMatrix = GL_TRUE;
960  break;
961  default:
962  gl_problem(ctx, "Bad matrix mode in gl_Scalef");
963  return;
964  }
965  m[0] *= x; m[4] *= y; m[8] *= z;
966  m[1] *= x; m[5] *= y; m[9] *= z;
967  m[2] *= x; m[6] *= y; m[10] *= z;
968  m[3] *= x; m[7] *= y; m[11] *= z;
969 }
970 
971 
972 
973 /*
974  * Execute a glTranslate call
975  */
977 {
978  GLfloat *m;
979  if (INSIDE_BEGIN_END(ctx)) {
980  gl_error( ctx, GL_INVALID_OPERATION, "glTranslate" );
981  return;
982  }
983  switch (ctx->Transform.MatrixMode) {
984  case GL_MODELVIEW:
985  m = ctx->ModelViewMatrix;
987  break;
988  case GL_PROJECTION:
989  m = ctx->ProjectionMatrix;
991  break;
992  case GL_TEXTURE:
993  m = ctx->TextureMatrix;
994  ctx->NewTextureMatrix = GL_TRUE;
995  break;
996  default:
997  gl_problem(ctx, "Bad matrix mode in gl_Translatef");
998  return;
999  }
1000 
1001  m[12] = m[0] * x + m[4] * y + m[8] * z + m[12];
1002  m[13] = m[1] * x + m[5] * y + m[9] * z + m[13];
1003  m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
1004  m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];
1005 }
1006 
1007 
1008 
1009 
1010 /*
1011  * Define a new viewport and reallocate auxillary buffers if the size of
1012  * the window (color buffer) has changed.
1013  */
1016 {
1017  if (width<0 || height<0) {
1018  gl_error( ctx, GL_INVALID_VALUE, "glViewport" );
1019  return;
1020  }
1021  if (INSIDE_BEGIN_END(ctx)) {
1022  gl_error( ctx, GL_INVALID_OPERATION, "glViewport" );
1023  return;
1024  }
1025 
1026  /* clamp width, and height to implementation dependent range */
1027  width = CLAMP( width, 1, MAX_WIDTH );
1028  height = CLAMP( height, 1, MAX_HEIGHT );
1029 
1030  /* Save viewport */
1031  ctx->Viewport.X = x;
1032  ctx->Viewport.Width = width;
1033  ctx->Viewport.Y = y;
1034  ctx->Viewport.Height = height;
1035 
1036  /* compute scale and bias values */
1037  ctx->Viewport.Sx = (GLfloat) width / 2.0F;
1038  ctx->Viewport.Tx = ctx->Viewport.Sx + x;
1039  ctx->Viewport.Sy = (GLfloat) height / 2.0F;
1040  ctx->Viewport.Ty = ctx->Viewport.Sy + y;
1041 
1042  ctx->NewState |= NEW_ALL; /* just to be safe */
1043 
1044  /* Check if window/buffer has been resized and if so, reallocate the
1045  * ancillary buffers.
1046  */
1047  gl_ResizeBuffersMESA(ctx);
1048 }
double GLdouble
Definition: gl.h:163
void gl_analyze_texture_matrix(GLcontext *ctx)
Definition: matrix.c:487
GLfloat ModelViewStack[MAX_MODELVIEW_STACK_DEPTH][16]
Definition: types.h:1287
Definition: matrix.c:193
GLint GLint GLsizei width
Definition: gl.h:1546
GLfloat Mat2[2][2]
Definition: matrix.c:190
void gl_Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height)
Definition: matrix.c:1014
Definition: matrix.c:195
static DNS_RECORDW r3
Definition: record.c:39
#define MATRIX_GENERAL
Definition: types.h:1242
GLfloat ModelViewMatrix[16]
Definition: types.h:1284
GLuint NewState
Definition: types.h:1355
#define GL_FALSE
Definition: gl.h:173
Definition: matrix.c:193
#define M(row, col)
GLfloat TextureMatrix[16]
Definition: types.h:1300
Definition: matrix.c:196
static GLboolean is_identity(const GLfloat m[16])
Definition: matrix.c:402
#define MATRIX_3D
Definition: types.h:1248
static GLfloat Identity[16]
Definition: matrix.c:127
static DNS_RECORDW r1
Definition: record.c:37
void gl_PopMatrix(GLcontext *ctx)
Definition: matrix.c:653
GLdouble n
Definition: glext.h:7729
static void matmul(GLfloat *product, const GLfloat *a, const GLfloat *b)
Definition: matrix.c:154
GLboolean NewProjectionMatrix
Definition: types.h:1290
GLboolean NewModelViewMatrix
Definition: types.h:1282
#define MAX_PROJECTION_STACK_DEPTH
Definition: config.h:69
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint ModelViewMatrixType
Definition: types.h:1283
GLfloat angle
Definition: glext.h:10853
#define MAX_TEXTURE_STACK_DEPTH
Definition: config.h:72
GLuint TextureMatrixType
Definition: types.h:1299
GLuint ProjectionMatrixType
Definition: types.h:1291
const GLfloat * m
Definition: glext.h:10848
#define INSIDE_BEGIN_END(CTX)
Definition: macros.h:135
Definition: matrix.c:195
void gl_LoadIdentity(GLcontext *ctx)
Definition: matrix.c:709
void gl_Scalef(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z)
Definition: matrix.c:940
struct dd_function_table Driver
Definition: types.h:1276
#define A(row, col)
#define m42
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: matrix.c:193
void gl_Frustum(GLcontext *ctx, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
Definition: matrix.c:511
void gl_Ortho(GLcontext *ctx, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
Definition: matrix.c:553
GLfloat NearFarStack[MAX_PROJECTION_STACK_DEPTH][2]
Definition: types.h:1295
#define a
Definition: ke_i.h:78
int GLsizei
Definition: gl.h:160
#define CLAMP(f, min, max)
Definition: tif_color.c:177
unsigned char GLboolean
Definition: gl.h:151
GLfloat ProjectionStack[MAX_PROJECTION_STACK_DEPTH][16]
Definition: types.h:1294
GLdouble GLdouble z
Definition: glext.h:5874
_STLP_DECLSPEC complex< float > _STLP_CALL cos(const complex< float > &)
#define MATRIX_2D
Definition: types.h:1246
#define m23
#define MATRIX_PERSPECTIVE
Definition: types.h:1245
#define m44
GLint GLint bottom
Definition: glext.h:7726
void gl_Translatef(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z)
Definition: matrix.c:976
#define b
Definition: ke_i.h:79
GLbyte ty
Definition: glext.h:8756
#define m11
Definition: matrix.c:194
GLuint ProjectionStackDepth
Definition: types.h:1293
#define NEW_ALL
Definition: types.h:1236
#define m21
#define m13
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define MAX_HEIGHT
Definition: config.h:131
void gl_PushMatrix(GLcontext *ctx)
Definition: matrix.c:603
#define MATRIX_ORTHO
Definition: types.h:1244
#define d
Definition: ke_i.h:81
#define MATRIX_2D_NO_ROT
Definition: types.h:1247
#define MAX_WIDTH
Definition: config.h:130
GLboolean NewTextureMatrix
Definition: types.h:1298
void gl_LoadMatrixf(GLcontext *ctx, const GLfloat *m)
Definition: matrix.c:738
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
#define m43
GLfloat ModelViewInv[16]
Definition: types.h:1285
static void invert_matrix_general(const GLfloat *m, GLfloat *out)
Definition: matrix.c:199
static DNS_RECORDW r2
Definition: record.c:38
const GLubyte * c
Definition: glext.h:8905
#define m22
#define GL_SQRT(X)
Definition: mmath.h:63
void gl_MultMatrixf(GLcontext *ctx, const GLfloat *m)
Definition: matrix.c:785
static FILE * out
Definition: regtests2xml.c:44
int xx
Definition: npserver.c:29
Definition: matrix.c:196
GLint left
Definition: glext.h:7726
#define m32
GLdouble GLdouble right
Definition: glext.h:10859
struct gl_transform_attrib Transform
Definition: types.h:1335
#define m34
#define GL_INVALID_VALUE
Definition: gl.h:695
#define m31
#define GL_INVALID_OPERATION
Definition: gl.h:696
GLfloat TextureStack[MAX_TEXTURE_STACK_DEPTH][16]
Definition: types.h:1302
void gl_Rotatef(GLcontext *ctx, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
Definition: matrix.c:927
Definition: ttei1.cpp:12
#define DEG2RAD
Definition: macros.h:268
#define GL_PROJECTION
Definition: gl.h:246
Definition: matrix.c:194
GLdouble s
Definition: gl.h:2039
GLuint ModelViewStackDepth
Definition: types.h:1286
void gl_rotation_matrix(GLfloat angle, GLfloat x, GLfloat y, GLfloat z, GLfloat m[])
Definition: matrix.c:814
unsigned int GLenum
Definition: gl.h:150
GLenum mode
Definition: glext.h:6217
void gl_problem(const GLcontext *ctx, const char *s)
Definition: context.c:1394
#define P(row, col)
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
void gl_error(GLcontext *ctx, GLenum error, const char *s)
Definition: context.c:1421
#define m14
void gl_MatrixMode(GLcontext *ctx, GLenum mode)
Definition: matrix.c:584
#define f
Definition: ke_i.h:83
#define GL_TRUE
Definition: gl.h:174
#define m24
Definition: ttei6.cpp:27
#define GL_INVALID_ENUM
Definition: gl.h:694
struct gl_viewport_attrib Viewport
Definition: types.h:1336
GLbyte GLbyte tz
Definition: glext.h:8756
#define GL_MODELVIEW
Definition: gl.h:245
#define B(row, col)
#define m12
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
Definition: matrix.c:195
Definition: matrix.c:196
Definition: matrix.c:194
Definition: matrix.c:195
void gl_ResizeBuffersMESA(GLcontext *ctx)
Definition: context.c:1497
float GLfloat
Definition: gl.h:161
GLuint TextureStackDepth
Definition: types.h:1301
#define GL_STACK_OVERFLOW
Definition: gl.h:697
GLfloat ProjectionMatrix[16]
Definition: types.h:1292
Definition: matrix.c:193
Definition: matrix.c:194
#define c
Definition: ke_i.h:80
void gl_analyze_modelview_matrix(GLcontext *ctx)
Definition: matrix.c:420
int GLint
Definition: gl.h:156
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
#define m33
#define GL_TEXTURE
Definition: gl.h:247
static void invert_matrix(const GLfloat *m, GLfloat *out)
Definition: matrix.c:290
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define m41
void gl_analyze_projection_matrix(GLcontext *ctx)
Definition: matrix.c:455
#define MAX_MODELVIEW_STACK_DEPTH
Definition: config.h:66
void f(int n) const
Definition: bind_test.cpp:124
Definition: matrix.c:196
#define GL_STACK_UNDERFLOW
Definition: gl.h:698
#define F(x, y, z)
Definition: md5.c:51
#define printf
Definition: config.h:203
#define MATRIX_IDENTITY
Definition: types.h:1243