VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_transform.c@ 71930

Last change on this file since 71930 was 69392, checked in by vboxsync, 7 years ago

GuestHost/OpenGL: scm updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 43.6 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_bits.h"
8#include "cr_mem.h"
9#include "state.h"
10#include "state/cr_statetypes.h"
11#include "state_internals.h"
12
13#ifdef WINDOWS
14#pragma warning( disable : 4514 )
15#endif
16
17/*
18 * This used to be a macro.
19 */
20static INLINE void
21LOADMATRIX( const CRmatrix *a )
22{
23 if (a->m00 == 1.0F && a->m01 == 0.0F && a->m02 == 0.0F && a->m03 == 0.0F &&
24 a->m10 == 0.0F && a->m11 == 1.0F && a->m12 == 0.0F && a->m13 == 0.0F &&
25 a->m20 == 0.0F && a->m21 == 0.0F && a->m22 == 1.0F && a->m23 == 0.0F &&
26 a->m30 == 0.0F && a->m31 == 0.0F && a->m32 == 0.0F && a->m33 == 1.0F) {
27 diff_api.LoadIdentity();
28 }
29 else {
30 GLfloat f[16];
31 f[0] = a->m00; f[1] = a->m01; f[2] = a->m02; f[3] = a->m03;
32 f[4] = a->m10; f[5] = a->m11; f[6] = a->m12; f[7] = a->m13;
33 f[8] = a->m20; f[9] = a->m21; f[10] = a->m22; f[11] = a->m23;
34 f[12] = a->m30; f[13] = a->m31; f[14] = a->m32; f[15] = a->m33;
35 diff_api.LoadMatrixf(f);
36 }
37}
38
39
40static void _math_transposef( GLfloat to[16], const GLfloat from[16] )
41{
42 to[0] = from[0];
43 to[1] = from[4];
44 to[2] = from[8];
45 to[3] = from[12];
46 to[4] = from[1];
47 to[5] = from[5];
48 to[6] = from[9];
49 to[7] = from[13];
50 to[8] = from[2];
51 to[9] = from[6];
52 to[10] = from[10];
53 to[11] = from[14];
54 to[12] = from[3];
55 to[13] = from[7];
56 to[14] = from[11];
57 to[15] = from[15];
58}
59
60static void _math_transposed( GLdouble to[16], const GLdouble from[16] )
61{
62 to[0] = from[0];
63 to[1] = from[4];
64 to[2] = from[8];
65 to[3] = from[12];
66 to[4] = from[1];
67 to[5] = from[5];
68 to[6] = from[9];
69 to[7] = from[13];
70 to[8] = from[2];
71 to[9] = from[6];
72 to[10] = from[10];
73 to[11] = from[14];
74 to[12] = from[3];
75 to[13] = from[7];
76 to[14] = from[11];
77 to[15] = from[15];
78}
79
80
81void
82crStateInitMatrixStack(CRMatrixStack *stack, int maxDepth)
83{
84 stack->maxDepth = maxDepth;
85 stack->depth = 0;
86 stack->stack = crAlloc(maxDepth * sizeof(CRmatrix));
87 crMatrixInit(&stack->stack[0]);
88 stack->top = stack->stack;
89}
90
91static void
92free_matrix_stack_data(CRMatrixStack *stack)
93{
94 crFree(stack->stack);
95}
96
97void crStateTransformDestroy(CRContext *ctx)
98{
99 CRTransformState *t = &ctx->transform;
100 unsigned int i;
101
102 free_matrix_stack_data(&(t->modelViewStack));
103 free_matrix_stack_data(&(t->projectionStack));
104 free_matrix_stack_data(&(t->colorStack));
105 for (i = 0 ; i < ctx->limits.maxTextureUnits; i++)
106 free_matrix_stack_data(&(t->textureStack[i]));
107 for (i = 0; i < CR_MAX_PROGRAM_MATRICES; i++)
108 free_matrix_stack_data(&(t->programStack[i]));
109
110 crFree( t->clipPlane );
111 crFree( t->clip );
112}
113
114void crStateTransformInit(CRContext *ctx)
115{
116 CRLimitsState *limits = &ctx->limits;
117 CRTransformState *t = &ctx->transform;
118 CRStateBits *sb = GetCurrentBits();
119 CRTransformBits *tb = &(sb->transform);
120 unsigned int i;
121
122 t->matrixMode = GL_MODELVIEW;
123 RESET(tb->matrixMode, ctx->bitid);
124
125 crStateInitMatrixStack(&t->modelViewStack, CR_MAX_MODELVIEW_STACK_DEPTH);
126 crStateInitMatrixStack(&t->projectionStack, CR_MAX_PROJECTION_STACK_DEPTH);
127 crStateInitMatrixStack(&t->colorStack, CR_MAX_COLOR_STACK_DEPTH);
128 for (i = 0 ; i < limits->maxTextureUnits ; i++)
129 crStateInitMatrixStack(&t->textureStack[i], CR_MAX_TEXTURE_STACK_DEPTH);
130 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
131 crStateInitMatrixStack(&t->programStack[i], CR_MAX_PROGRAM_MATRIX_STACK_DEPTH);
132 t->currentStack = &(t->modelViewStack);
133
134 /* dirty bits */
135 RESET(tb->modelviewMatrix, ctx->bitid);
136 RESET(tb->projectionMatrix, ctx->bitid);
137 RESET(tb->colorMatrix, ctx->bitid);
138 RESET(tb->textureMatrix, ctx->bitid);
139 RESET(tb->programMatrix, ctx->bitid);
140 tb->currentMatrix = tb->modelviewMatrix;
141
142 t->normalize = GL_FALSE;
143 RESET(tb->enable, ctx->bitid);
144
145 t->clipPlane = (GLvectord *) crCalloc (sizeof (GLvectord) * CR_MAX_CLIP_PLANES);
146 t->clip = (GLboolean *) crCalloc (sizeof (GLboolean) * CR_MAX_CLIP_PLANES);
147 for (i = 0; i < CR_MAX_CLIP_PLANES; i++)
148 {
149 t->clipPlane[i].x = 0.0f;
150 t->clipPlane[i].y = 0.0f;
151 t->clipPlane[i].z = 0.0f;
152 t->clipPlane[i].w = 0.0f;
153 t->clip[i] = GL_FALSE;
154 }
155 RESET(tb->clipPlane, ctx->bitid);
156
157#ifdef CR_OPENGL_VERSION_1_2
158 t->rescaleNormals = GL_FALSE;
159#endif
160#ifdef CR_IBM_rasterpos_clip
161 t->rasterPositionUnclipped = GL_FALSE;
162#endif
163
164 t->modelViewProjectionValid = 0;
165
166 RESET(tb->dirty, ctx->bitid);
167}
168
169
170/*
171 * Compute the product of the modelview and projection matrices
172 */
173void crStateTransformUpdateTransform(CRTransformState *t)
174{
175 const CRmatrix *m1 = t->projectionStack.top;
176 const CRmatrix *m2 = t->modelViewStack.top;
177 CRmatrix *m = &(t->modelViewProjection);
178 crMatrixMultiply(m, m1, m2);
179 t->modelViewProjectionValid = 1;
180}
181
182void crStateTransformXformPoint(CRTransformState *t, GLvectorf *p)
183{
184 /* XXX is this flag really needed? We may be covering a bug elsewhere */
185 if (!t->modelViewProjectionValid)
186 crStateTransformUpdateTransform(t);
187
188 crStateTransformXformPointMatrixf(&(t->modelViewProjection), p);
189}
190
191void crStateTransformXformPointMatrixf(const CRmatrix *m, GLvectorf *p)
192{
193 GLfloat x = p->x;
194 GLfloat y = p->y;
195 GLfloat z = p->z;
196 GLfloat w = p->w;
197
198 p->x = m->m00*x + m->m10*y + m->m20*z + m->m30*w;
199 p->y = m->m01*x + m->m11*y + m->m21*z + m->m31*w;
200 p->z = m->m02*x + m->m12*y + m->m22*z + m->m32*w;
201 p->w = m->m03*x + m->m13*y + m->m23*z + m->m33*w;
202}
203
204void crStateTransformXformPointMatrixd(const CRmatrix *m, GLvectord *p)
205{
206 GLdouble x = p->x;
207 GLdouble y = p->y;
208 GLdouble z = p->z;
209 GLdouble w = p->w;
210
211 p->x = (GLdouble) (m->m00*x + m->m10*y + m->m20*z + m->m30*w);
212 p->y = (GLdouble) (m->m01*x + m->m11*y + m->m21*z + m->m31*w);
213 p->z = (GLdouble) (m->m02*x + m->m12*y + m->m22*z + m->m32*w);
214 p->w = (GLdouble) (m->m03*x + m->m13*y + m->m23*z + m->m33*w);
215}
216
217void STATE_APIENTRY crStateClipPlane (GLenum plane, const GLdouble *equation)
218{
219 CRContext *g = GetCurrentContext();
220 CRTransformState *t = &g->transform;
221 CRStateBits *sb = GetCurrentBits();
222 CRTransformBits *tb = &(sb->transform);
223 GLvectord e;
224 unsigned int i;
225 CRmatrix inv;
226
227 e.x = equation[0];
228 e.y = equation[1];
229 e.z = equation[2];
230 e.w = equation[3];
231
232 if (g->current.inBeginEnd)
233 {
234 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
235 "ClipPlane called in begin/end");
236 return;
237 }
238
239 FLUSH();
240
241 i = plane - GL_CLIP_PLANE0;
242 if (i >= g->limits.maxClipPlanes)
243 {
244 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
245 "ClipPlane called with bad enumerant: %d", plane);
246 return;
247 }
248
249 crMatrixInvertTranspose(&inv, t->modelViewStack.top);
250 crStateTransformXformPointMatrixd (&inv, &e);
251 t->clipPlane[i] = e;
252 DIRTY(tb->clipPlane, g->neg_bitid);
253 DIRTY(tb->dirty, g->neg_bitid);
254}
255
256void STATE_APIENTRY crStateMatrixMode(GLenum e)
257{
258 CRContext *g = GetCurrentContext();
259 CRTransformState *t = &(g->transform);
260 CRTextureState *tex = &(g->texture);
261 CRStateBits *sb = GetCurrentBits();
262 CRTransformBits *tb = &(sb->transform);
263
264 if (g->current.inBeginEnd)
265 {
266 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "MatrixMode called in begin/end");
267 return;
268 }
269
270 FLUSH();
271
272 switch (e)
273 {
274 case GL_MODELVIEW:
275 t->currentStack = &(t->modelViewStack);
276 t->matrixMode = GL_MODELVIEW;
277 tb->currentMatrix = tb->modelviewMatrix;
278 break;
279 case GL_PROJECTION:
280 t->currentStack = &(t->projectionStack);
281 t->matrixMode = GL_PROJECTION;
282 tb->currentMatrix = tb->projectionMatrix;
283 break;
284 case GL_TEXTURE:
285 t->currentStack = &(t->textureStack[tex->curTextureUnit]);
286 t->matrixMode = GL_TEXTURE;
287 tb->currentMatrix = tb->textureMatrix;
288 break;
289 case GL_COLOR:
290 t->currentStack = &(t->colorStack);
291 t->matrixMode = GL_COLOR;
292 tb->currentMatrix = tb->colorMatrix;
293 break;
294 case GL_MATRIX0_NV:
295 case GL_MATRIX1_NV:
296 case GL_MATRIX2_NV:
297 case GL_MATRIX3_NV:
298 case GL_MATRIX4_NV:
299 case GL_MATRIX5_NV:
300 case GL_MATRIX6_NV:
301 case GL_MATRIX7_NV:
302 if (g->extensions.NV_vertex_program) {
303 const GLint i = e - GL_MATRIX0_NV;
304 t->currentStack = &(t->programStack[i]);
305 t->matrixMode = e;
306 tb->currentMatrix = tb->programMatrix;
307 }
308 else {
309 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid matrix mode: %d", e);
310 return;
311 }
312 break;
313 case GL_MATRIX0_ARB:
314 case GL_MATRIX1_ARB:
315 case GL_MATRIX2_ARB:
316 case GL_MATRIX3_ARB:
317 case GL_MATRIX4_ARB:
318 case GL_MATRIX5_ARB:
319 case GL_MATRIX6_ARB:
320 case GL_MATRIX7_ARB:
321 /* Note: the NV and ARB program matrices are the same, but
322 * use different enumerants.
323 */
324 if (g->extensions.ARB_vertex_program) {
325 const GLint i = e - GL_MATRIX0_ARB;
326 t->currentStack = &(t->programStack[i]);
327 t->matrixMode = e;
328 tb->currentMatrix = tb->programMatrix;
329 }
330 else {
331 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid matrix mode: %d", e);
332 return;
333 }
334 break;
335 default:
336 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid matrix mode: %d", e);
337 return;
338 }
339 DIRTY(tb->matrixMode, g->neg_bitid);
340 DIRTY(tb->dirty, g->neg_bitid);
341
342 CRASSERT(t->currentStack->top == t->currentStack->stack + t->currentStack->depth);
343}
344
345void STATE_APIENTRY crStateLoadIdentity()
346{
347 CRContext *g = GetCurrentContext();
348 CRTransformState *t = &(g->transform);
349 CRStateBits *sb = GetCurrentBits();
350 CRTransformBits *tb = &(sb->transform);
351
352 if (g->current.inBeginEnd)
353 {
354 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
355 "LoadIdentity called in begin/end");
356 return;
357 }
358
359 FLUSH();
360
361 crMatrixInit(t->currentStack->top);
362 t->modelViewProjectionValid = 0;
363
364 DIRTY(tb->currentMatrix, g->neg_bitid);
365 DIRTY(tb->dirty, g->neg_bitid);
366}
367
368void STATE_APIENTRY crStatePopMatrix()
369{
370 CRContext *g = GetCurrentContext();
371 CRTransformState *t = &g->transform;
372 CRStateBits *sb = GetCurrentBits();
373 CRTransformBits *tb = &(sb->transform);
374
375 if (g->current.inBeginEnd)
376 {
377 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "PopMatrix called in begin/end");
378 return;
379 }
380
381 FLUSH();
382
383 if (t->currentStack->depth == 0)
384 {
385 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "PopMatrix of empty stack.");
386 return;
387 }
388
389 CRASSERT(t->currentStack->top == t->currentStack->stack + t->currentStack->depth);
390
391 t->currentStack->depth--;
392 t->currentStack->top = t->currentStack->stack + t->currentStack->depth;
393
394 t->modelViewProjectionValid = 0;
395
396 DIRTY(tb->currentMatrix, g->neg_bitid);
397 DIRTY(tb->dirty, g->neg_bitid);
398}
399
400void STATE_APIENTRY crStatePushMatrix()
401{
402 CRContext *g = GetCurrentContext();
403 CRTransformState *t = &g->transform;
404 CRStateBits *sb = GetCurrentBits();
405 CRTransformBits *tb = &(sb->transform);
406
407 if (g->current.inBeginEnd)
408 {
409 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "PushMatrix called in begin/end");
410 return;
411 }
412
413 FLUSH();
414
415 if (t->currentStack->depth + 1 >= t->currentStack->maxDepth)
416 {
417 crStateError(__LINE__, __FILE__, GL_STACK_OVERFLOW, "PushMatrix pass the end of allocated stack");
418 return;
419 }
420
421 CRASSERT(t->currentStack->top == t->currentStack->stack + t->currentStack->depth);
422 /* Perform the copy */
423 *(t->currentStack->top + 1) = *(t->currentStack->top);
424
425 /* Move the stack pointer */
426 t->currentStack->depth++;
427 t->currentStack->top = t->currentStack->stack + t->currentStack->depth;
428
429 DIRTY(tb->currentMatrix, g->neg_bitid);
430 DIRTY(tb->dirty, g->neg_bitid);
431}
432
433
434/* Load a CRMatrix */
435void crStateLoadMatrix(const CRmatrix *m)
436{
437 CRContext *g = GetCurrentContext();
438 CRTransformState *t = &(g->transform);
439 CRStateBits *sb = GetCurrentBits();
440 CRTransformBits *tb = &(sb->transform);
441
442 if (g->current.inBeginEnd)
443 {
444 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
445 "LoadMatrix called in begin/end");
446 return;
447 }
448
449 FLUSH();
450
451 CRASSERT(t->currentStack->top == t->currentStack->stack + t->currentStack->depth);
452 *t->currentStack->top = *m;
453 t->modelViewProjectionValid = 0;
454 DIRTY(tb->currentMatrix, g->neg_bitid);
455 DIRTY(tb->dirty, g->neg_bitid);
456}
457
458
459
460void STATE_APIENTRY crStateLoadMatrixf(const GLfloat *m1)
461{
462 CRContext *g = GetCurrentContext();
463 CRTransformState *t = &(g->transform);
464 CRStateBits *sb = GetCurrentBits();
465 CRTransformBits *tb = &(sb->transform);
466
467 if (g->current.inBeginEnd)
468 {
469 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
470 "LoadMatrixf called in begin/end");
471 return;
472 }
473
474 FLUSH();
475
476 crMatrixInitFromFloats(t->currentStack->top, m1);
477 t->modelViewProjectionValid = 0;
478 DIRTY(tb->currentMatrix, g->neg_bitid);
479 DIRTY(tb->dirty, g->neg_bitid);
480}
481
482
483void STATE_APIENTRY crStateLoadMatrixd(const GLdouble *m1)
484{
485 CRContext *g = GetCurrentContext();
486 CRTransformState *t = &(g->transform);
487 CRStateBits *sb = GetCurrentBits();
488 CRTransformBits *tb = &(sb->transform);
489
490 if (g->current.inBeginEnd)
491 {
492 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
493 "LoadMatrixd called in begin/end");
494 return;
495 }
496
497 FLUSH();
498
499 crMatrixInitFromDoubles(t->currentStack->top, m1);
500 t->modelViewProjectionValid = 0;
501 DIRTY(tb->currentMatrix, g->neg_bitid);
502 DIRTY(tb->dirty, g->neg_bitid);
503}
504
505
506void STATE_APIENTRY crStateLoadTransposeMatrixfARB(const GLfloat *m1)
507{
508 GLfloat tm[16];
509 if (!m1) return;
510 _math_transposef(tm, m1);
511 crStateLoadMatrixf(tm);
512}
513
514void STATE_APIENTRY crStateLoadTransposeMatrixdARB(const GLdouble *m1)
515{
516 GLdouble tm[16];
517 if (!m1) return;
518 _math_transposed(tm, m1);
519 crStateLoadMatrixd(tm);
520}
521
522/* This code is based on the Pomegranate stuff.
523 ** The theory is that by preloading everything,
524 ** the compiler could do optimizations that
525 ** were not doable in the array version
526 ** I'm not too sure with a PII with 4 registers
527 ** that this really helps.
528 */
529void STATE_APIENTRY crStateMultMatrixf(const GLfloat *m1)
530{
531 CRContext *g = GetCurrentContext();
532 CRTransformState *t = &(g->transform);
533 CRStateBits *sb = GetCurrentBits();
534 CRTransformBits *tb = &(sb->transform);
535 CRmatrix *m = t->currentStack->top;
536
537 const GLdefault lm00 = m->m00;
538 const GLdefault lm01 = m->m01;
539 const GLdefault lm02 = m->m02;
540 const GLdefault lm03 = m->m03;
541 const GLdefault lm10 = m->m10;
542 const GLdefault lm11 = m->m11;
543 const GLdefault lm12 = m->m12;
544 const GLdefault lm13 = m->m13;
545 const GLdefault lm20 = m->m20;
546 const GLdefault lm21 = m->m21;
547 const GLdefault lm22 = m->m22;
548 const GLdefault lm23 = m->m23;
549 const GLdefault lm30 = m->m30;
550 const GLdefault lm31 = m->m31;
551 const GLdefault lm32 = m->m32;
552 const GLdefault lm33 = m->m33;
553 const GLdefault rm00 = (GLdefault) m1[0];
554 const GLdefault rm01 = (GLdefault) m1[1];
555 const GLdefault rm02 = (GLdefault) m1[2];
556 const GLdefault rm03 = (GLdefault) m1[3];
557 const GLdefault rm10 = (GLdefault) m1[4];
558 const GLdefault rm11 = (GLdefault) m1[5];
559 const GLdefault rm12 = (GLdefault) m1[6];
560 const GLdefault rm13 = (GLdefault) m1[7];
561 const GLdefault rm20 = (GLdefault) m1[8];
562 const GLdefault rm21 = (GLdefault) m1[9];
563 const GLdefault rm22 = (GLdefault) m1[10];
564 const GLdefault rm23 = (GLdefault) m1[11];
565 const GLdefault rm30 = (GLdefault) m1[12];
566 const GLdefault rm31 = (GLdefault) m1[13];
567 const GLdefault rm32 = (GLdefault) m1[14];
568 const GLdefault rm33 = (GLdefault) m1[15];
569
570 if (g->current.inBeginEnd)
571 {
572 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "MultMatrixf called in begin/end");
573 return;
574 }
575
576 FLUSH();
577
578 m->m00 = lm00*rm00 + lm10*rm01 + lm20*rm02 + lm30*rm03;
579 m->m01 = lm01*rm00 + lm11*rm01 + lm21*rm02 + lm31*rm03;
580 m->m02 = lm02*rm00 + lm12*rm01 + lm22*rm02 + lm32*rm03;
581 m->m03 = lm03*rm00 + lm13*rm01 + lm23*rm02 + lm33*rm03;
582 m->m10 = lm00*rm10 + lm10*rm11 + lm20*rm12 + lm30*rm13;
583 m->m11 = lm01*rm10 + lm11*rm11 + lm21*rm12 + lm31*rm13;
584 m->m12 = lm02*rm10 + lm12*rm11 + lm22*rm12 + lm32*rm13;
585 m->m13 = lm03*rm10 + lm13*rm11 + lm23*rm12 + lm33*rm13;
586 m->m20 = lm00*rm20 + lm10*rm21 + lm20*rm22 + lm30*rm23;
587 m->m21 = lm01*rm20 + lm11*rm21 + lm21*rm22 + lm31*rm23;
588 m->m22 = lm02*rm20 + lm12*rm21 + lm22*rm22 + lm32*rm23;
589 m->m23 = lm03*rm20 + lm13*rm21 + lm23*rm22 + lm33*rm23;
590 m->m30 = lm00*rm30 + lm10*rm31 + lm20*rm32 + lm30*rm33;
591 m->m31 = lm01*rm30 + lm11*rm31 + lm21*rm32 + lm31*rm33;
592 m->m32 = lm02*rm30 + lm12*rm31 + lm22*rm32 + lm32*rm33;
593 m->m33 = lm03*rm30 + lm13*rm31 + lm23*rm32 + lm33*rm33;
594
595 t->modelViewProjectionValid = 0;
596
597 DIRTY(tb->currentMatrix, g->neg_bitid);
598 DIRTY(tb->dirty, g->neg_bitid);
599}
600
601void STATE_APIENTRY crStateMultMatrixd(const GLdouble *m1)
602{
603 CRContext *g = GetCurrentContext();
604 CRTransformState *t = &(g->transform);
605 CRStateBits *sb = GetCurrentBits();
606 CRTransformBits *tb = &(sb->transform);
607 CRmatrix *m = t->currentStack->top;
608 const GLdefault lm00 = m->m00;
609 const GLdefault lm01 = m->m01;
610 const GLdefault lm02 = m->m02;
611 const GLdefault lm03 = m->m03;
612 const GLdefault lm10 = m->m10;
613 const GLdefault lm11 = m->m11;
614 const GLdefault lm12 = m->m12;
615 const GLdefault lm13 = m->m13;
616 const GLdefault lm20 = m->m20;
617 const GLdefault lm21 = m->m21;
618 const GLdefault lm22 = m->m22;
619 const GLdefault lm23 = m->m23;
620 const GLdefault lm30 = m->m30;
621 const GLdefault lm31 = m->m31;
622 const GLdefault lm32 = m->m32;
623 const GLdefault lm33 = m->m33;
624 const GLdefault rm00 = (GLdefault) m1[0];
625 const GLdefault rm01 = (GLdefault) m1[1];
626 const GLdefault rm02 = (GLdefault) m1[2];
627 const GLdefault rm03 = (GLdefault) m1[3];
628 const GLdefault rm10 = (GLdefault) m1[4];
629 const GLdefault rm11 = (GLdefault) m1[5];
630 const GLdefault rm12 = (GLdefault) m1[6];
631 const GLdefault rm13 = (GLdefault) m1[7];
632 const GLdefault rm20 = (GLdefault) m1[8];
633 const GLdefault rm21 = (GLdefault) m1[9];
634 const GLdefault rm22 = (GLdefault) m1[10];
635 const GLdefault rm23 = (GLdefault) m1[11];
636 const GLdefault rm30 = (GLdefault) m1[12];
637 const GLdefault rm31 = (GLdefault) m1[13];
638 const GLdefault rm32 = (GLdefault) m1[14];
639 const GLdefault rm33 = (GLdefault) m1[15];
640
641 if (g->current.inBeginEnd)
642 {
643 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "MultMatrixd called in begin/end");
644 return;
645 }
646
647 FLUSH();
648
649 m->m00 = lm00*rm00 + lm10*rm01 + lm20*rm02 + lm30*rm03;
650 m->m01 = lm01*rm00 + lm11*rm01 + lm21*rm02 + lm31*rm03;
651 m->m02 = lm02*rm00 + lm12*rm01 + lm22*rm02 + lm32*rm03;
652 m->m03 = lm03*rm00 + lm13*rm01 + lm23*rm02 + lm33*rm03;
653 m->m10 = lm00*rm10 + lm10*rm11 + lm20*rm12 + lm30*rm13;
654 m->m11 = lm01*rm10 + lm11*rm11 + lm21*rm12 + lm31*rm13;
655 m->m12 = lm02*rm10 + lm12*rm11 + lm22*rm12 + lm32*rm13;
656 m->m13 = lm03*rm10 + lm13*rm11 + lm23*rm12 + lm33*rm13;
657 m->m20 = lm00*rm20 + lm10*rm21 + lm20*rm22 + lm30*rm23;
658 m->m21 = lm01*rm20 + lm11*rm21 + lm21*rm22 + lm31*rm23;
659 m->m22 = lm02*rm20 + lm12*rm21 + lm22*rm22 + lm32*rm23;
660 m->m23 = lm03*rm20 + lm13*rm21 + lm23*rm22 + lm33*rm23;
661 m->m30 = lm00*rm30 + lm10*rm31 + lm20*rm32 + lm30*rm33;
662 m->m31 = lm01*rm30 + lm11*rm31 + lm21*rm32 + lm31*rm33;
663 m->m32 = lm02*rm30 + lm12*rm31 + lm22*rm32 + lm32*rm33;
664 m->m33 = lm03*rm30 + lm13*rm31 + lm23*rm32 + lm33*rm33;
665
666 t->modelViewProjectionValid = 0;
667
668 DIRTY(tb->currentMatrix, g->neg_bitid);
669 DIRTY(tb->dirty, g->neg_bitid);
670}
671
672void STATE_APIENTRY crStateMultTransposeMatrixfARB(const GLfloat *m1)
673{
674 GLfloat tm[16];
675 if (!m1) return;
676 _math_transposef(tm, m1);
677 crStateMultMatrixf(tm);
678}
679
680void STATE_APIENTRY crStateMultTransposeMatrixdARB(const GLdouble *m1)
681{
682 GLdouble tm[16];
683 if (!m1) return;
684 _math_transposed(tm, m1);
685 crStateMultMatrixd(tm);
686}
687
688void STATE_APIENTRY crStateTranslatef(GLfloat x_arg, GLfloat y_arg, GLfloat z_arg)
689{
690 CRContext *g = GetCurrentContext();
691 CRTransformState *t = &(g->transform);
692 CRStateBits *sb = GetCurrentBits();
693 CRTransformBits *tb = &(sb->transform);
694
695 if (g->current.inBeginEnd)
696 {
697 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
698 "Translatef called in begin/end");
699 return;
700 }
701
702 FLUSH();
703
704 crMatrixTranslate(t->currentStack->top, x_arg, y_arg, z_arg);
705 t->modelViewProjectionValid = 0;
706 DIRTY(tb->currentMatrix, g->neg_bitid);
707 DIRTY(tb->dirty, g->neg_bitid);
708}
709
710
711void STATE_APIENTRY crStateTranslated(GLdouble x_arg, GLdouble y_arg, GLdouble z_arg)
712{
713 CRContext *g = GetCurrentContext();
714 CRTransformState *t = &(g->transform);
715 CRStateBits *sb = GetCurrentBits();
716 CRTransformBits *tb = &(sb->transform);
717
718 if (g->current.inBeginEnd)
719 {
720 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
721 "Translated called in begin/end");
722 return;
723 }
724
725 FLUSH();
726
727 crMatrixTranslate(t->currentStack->top, (float)x_arg, (float)y_arg, (float)z_arg);
728 t->modelViewProjectionValid = 0;
729 DIRTY(tb->currentMatrix, g->neg_bitid);
730 DIRTY(tb->dirty, g->neg_bitid);
731}
732
733
734void STATE_APIENTRY crStateRotatef(GLfloat ang, GLfloat x, GLfloat y, GLfloat z)
735{
736 CRContext *g = GetCurrentContext();
737 CRTransformState *t = &(g->transform);
738 CRStateBits *sb = GetCurrentBits();
739 CRTransformBits *tb = &(sb->transform);
740
741 if (g->current.inBeginEnd)
742 {
743 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
744 "Rotatef called in begin/end");
745 return;
746 }
747
748 FLUSH();
749
750 crMatrixRotate(t->currentStack->top, ang, x, y, z);
751 t->modelViewProjectionValid = 0;
752 DIRTY(tb->currentMatrix, g->neg_bitid);
753 DIRTY(tb->dirty, g->neg_bitid);
754}
755
756void STATE_APIENTRY crStateRotated(GLdouble ang, GLdouble x, GLdouble y, GLdouble z)
757{
758 CRContext *g = GetCurrentContext();
759 CRTransformState *t = &(g->transform);
760 CRStateBits *sb = GetCurrentBits();
761 CRTransformBits *tb = &(sb->transform);
762
763 if (g->current.inBeginEnd)
764 {
765 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
766 "Rotated called in begin/end");
767 return;
768 }
769
770 FLUSH();
771
772 crMatrixRotate(t->currentStack->top, (float)ang, (float)x, (float)y, (float)z);
773 t->modelViewProjectionValid = 0;
774 DIRTY(tb->currentMatrix, g->neg_bitid);
775 DIRTY(tb->dirty, g->neg_bitid);
776}
777
778void STATE_APIENTRY crStateScalef (GLfloat x_arg, GLfloat y_arg, GLfloat z_arg)
779{
780 CRContext *g = GetCurrentContext();
781 CRTransformState *t = &(g->transform);
782 CRStateBits *sb = GetCurrentBits();
783 CRTransformBits *tb = &(sb->transform);
784
785 if (g->current.inBeginEnd)
786 {
787 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
788 "Scalef called in begin/end");
789 return;
790 }
791
792 FLUSH();
793
794 crMatrixScale(t->currentStack->top, x_arg, y_arg, z_arg);
795 t->modelViewProjectionValid = 0;
796 DIRTY(tb->currentMatrix, g->neg_bitid);
797 DIRTY(tb->dirty, g->neg_bitid);
798}
799
800void STATE_APIENTRY crStateScaled (GLdouble x_arg, GLdouble y_arg, GLdouble z_arg)
801{
802 CRContext *g = GetCurrentContext();
803 CRTransformState *t = &(g->transform);
804 CRStateBits *sb = GetCurrentBits();
805 CRTransformBits *tb = &(sb->transform);
806
807 if (g->current.inBeginEnd)
808 {
809 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
810 "Scaled called in begin/end");
811 return;
812 }
813
814 FLUSH();
815
816 crMatrixScale(t->currentStack->top, (float)x_arg, (float)y_arg, (float)z_arg);
817 t->modelViewProjectionValid = 0;
818 DIRTY(tb->currentMatrix, g->neg_bitid);
819 DIRTY(tb->dirty, g->neg_bitid);
820}
821
822void STATE_APIENTRY crStateFrustum(GLdouble left, GLdouble right,
823 GLdouble bottom, GLdouble top,
824 GLdouble zNear, GLdouble zFar)
825{
826 CRContext *g = GetCurrentContext();
827 CRTransformState *t = &(g->transform);
828 CRStateBits *sb = GetCurrentBits();
829 CRTransformBits *tb = &(sb->transform);
830
831 if (g->current.inBeginEnd)
832 {
833 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
834 "Frustum called in begin/end");
835 return;
836 }
837
838 FLUSH();
839
840 crMatrixFrustum(t->currentStack->top, (float)left, (float)right, (float)bottom, (float)top, (float)zNear, (float)zFar);
841 t->modelViewProjectionValid = 0;
842 DIRTY(tb->currentMatrix, g->neg_bitid);
843 DIRTY(tb->dirty, g->neg_bitid);
844}
845
846void STATE_APIENTRY crStateOrtho(GLdouble left, GLdouble right,
847 GLdouble bottom, GLdouble top,
848 GLdouble zNear, GLdouble zFar)
849{
850 CRContext *g = GetCurrentContext();
851 CRTransformState *t = &(g->transform);
852 CRStateBits *sb = GetCurrentBits();
853 CRTransformBits *tb = &(sb->transform);
854
855 if (g->current.inBeginEnd)
856 {
857 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
858 "Ortho called in begin/end");
859 return;
860 }
861
862 FLUSH();
863
864 crMatrixOrtho(t->currentStack->top, (float)left, (float)right, (float)bottom, (float)top, (float)zNear, (float)zFar);
865 t->modelViewProjectionValid = 0;
866 DIRTY(tb->currentMatrix, g->neg_bitid);
867 DIRTY(tb->dirty, g->neg_bitid);
868}
869
870void STATE_APIENTRY crStateGetClipPlane(GLenum plane, GLdouble *equation)
871{
872 CRContext *g = GetCurrentContext();
873 CRTransformState *t = &g->transform;
874 unsigned int i;
875
876 if (g->current.inBeginEnd)
877 {
878 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
879 "glGetClipPlane called in begin/end");
880 return;
881 }
882
883 i = plane - GL_CLIP_PLANE0;
884 if (i >= g->limits.maxClipPlanes)
885 {
886 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
887 "GetClipPlane called with bad enumerant: %d", plane);
888 return;
889 }
890
891 equation[0] = t->clipPlane[i].x;
892 equation[1] = t->clipPlane[i].y;
893 equation[2] = t->clipPlane[i].z;
894 equation[3] = t->clipPlane[i].w;
895}
896
897void crStateTransformSwitch( CRTransformBits *t, CRbitvalue *bitID,
898 CRContext *fromCtx, CRContext *toCtx )
899{
900 const GLuint maxTextureUnits = toCtx->limits.maxTextureUnits;
901 CRTransformState *from = &(fromCtx->transform);
902 CRTransformState *to = &(toCtx->transform);
903 GLuint i, j;
904 unsigned int checktex = 0;
905 CRbitvalue nbitID[CR_MAX_BITARRAY];
906
907 for (j=0;j<CR_MAX_BITARRAY;j++)
908 nbitID[j] = ~bitID[j];
909
910 if (CHECKDIRTY(t->enable, bitID))
911 {
912 glAble able[2];
913 able[0] = diff_api.Disable;
914 able[1] = diff_api.Enable;
915 if (from->normalize != to->normalize) {
916 if (to->normalize == GL_TRUE)
917 diff_api.Enable(GL_NORMALIZE);
918 else
919 diff_api.Disable(GL_NORMALIZE);
920 FILLDIRTY(t->enable);
921 FILLDIRTY(t->dirty);
922 }
923#ifdef CR_OPENGL_VERSION_1_2
924 if (from->rescaleNormals != to->rescaleNormals)
925 {
926 able[to->rescaleNormals](GL_RESCALE_NORMAL);
927 FILLDIRTY(t->enable);
928 FILLDIRTY(t->dirty);
929 }
930#else
931 (void) able;
932#endif
933#ifdef CR_IBM_rasterpos_clip
934 if (from->rasterPositionUnclipped != to->rasterPositionUnclipped)
935 {
936 able[to->rasterPositionUnclipped](GL_RASTER_POSITION_UNCLIPPED_IBM);
937 FILLDIRTY(t->enable);
938 FILLDIRTY(t->dirty);
939 }
940#endif
941 CLEARDIRTY(t->enable, nbitID);
942 }
943
944 if (CHECKDIRTY(t->clipPlane, bitID)) {
945 diff_api.MatrixMode(GL_MODELVIEW);
946 diff_api.PushMatrix();
947 diff_api.LoadIdentity();
948 for (i=0; i<CR_MAX_CLIP_PLANES; i++) {
949 if (from->clipPlane[i].x != to->clipPlane[i].x ||
950 from->clipPlane[i].y != to->clipPlane[i].y ||
951 from->clipPlane[i].z != to->clipPlane[i].z ||
952 from->clipPlane[i].w != to->clipPlane[i].w) {
953
954 GLdouble cp[4];
955 cp[0] = to->clipPlane[i].x;
956 cp[1] = to->clipPlane[i].y;
957 cp[2] = to->clipPlane[i].z;
958 cp[3] = to->clipPlane[i].w;
959
960 diff_api.ClipPlane(GL_CLIP_PLANE0 + i, (const GLdouble *)(cp));
961
962 FILLDIRTY(t->clipPlane);
963 FILLDIRTY(t->dirty);
964 }
965 }
966 diff_api.PopMatrix();
967 CLEARDIRTY(t->clipPlane, nbitID);
968 }
969
970 /* If the matrix stack depths don't match when we're
971 * updating the context - we can update the wrong matrix
972 * and get some lovely effects!!
973 * So we troll each depth list here and Pop & Push the matrix stack
974 * to bring it right up to date before checking the current
975 * matrix.
976 *
977 * - Alan H.
978 */
979 if ( (from->modelViewStack.depth != to->modelViewStack.depth) ||
980 CHECKDIRTY(t->modelviewMatrix, bitID) )
981 {
982 GLuint td = to->modelViewStack.depth;
983 GLuint fd = from->modelViewStack.depth;
984
985 if (td != fd ||
986 !crMatrixIsEqual(to->modelViewStack.top, from->modelViewStack.top))
987 {
988 diff_api.MatrixMode(GL_MODELVIEW);
989
990 if (fd > td)
991 {
992 for (i = td; i < fd; i++)
993 {
994 diff_api.PopMatrix();
995 }
996 fd = td;
997 }
998
999 for (i = fd; i <= td; i++)
1000 {
1001 LOADMATRIX(to->modelViewStack.stack + i);
1002 FILLDIRTY(t->modelviewMatrix);
1003 FILLDIRTY(t->dirty);
1004
1005 /* Don't want to push on the current matrix */
1006 if (i != to->modelViewStack.depth)
1007 diff_api.PushMatrix();
1008 }
1009 }
1010 CLEARDIRTY(t->modelviewMatrix, nbitID);
1011 }
1012
1013 /* Projection matrix */
1014 if ( (from->projectionStack.depth != to->projectionStack.depth) ||
1015 CHECKDIRTY(t->projectionMatrix, bitID) )
1016 {
1017 GLuint td = to->projectionStack.depth;
1018 GLuint fd = from->projectionStack.depth;
1019
1020 if (td != fd ||
1021 !crMatrixIsEqual(to->projectionStack.top, from->projectionStack.top)) {
1022
1023 diff_api.MatrixMode(GL_PROJECTION);
1024
1025 if (fd > td)
1026 {
1027 for (i = td; i < fd; i++)
1028 {
1029 diff_api.PopMatrix();
1030 }
1031 fd = td;
1032 }
1033
1034 for (i = fd; i <= td; i++)
1035 {
1036 LOADMATRIX(to->projectionStack.stack + i);
1037 FILLDIRTY(t->projectionMatrix);
1038 FILLDIRTY(t->dirty);
1039
1040 /* Don't want to push on the current matrix */
1041 if (i != to->projectionStack.depth)
1042 diff_api.PushMatrix();
1043 }
1044 }
1045 CLEARDIRTY(t->projectionMatrix, nbitID);
1046 }
1047
1048 /* Texture matrices */
1049 for (i = 0 ; i < maxTextureUnits ; i++)
1050 if (from->textureStack[i].depth != to->textureStack[i].depth)
1051 checktex = 1;
1052
1053 if ( checktex || CHECKDIRTY(t->textureMatrix, bitID) )
1054 {
1055 for (j = 0 ; j < maxTextureUnits ; j++)
1056 {
1057 GLuint td = to->textureStack[j].depth;
1058 GLuint fd = from->textureStack[j].depth;
1059
1060 if (td != fd ||
1061 !crMatrixIsEqual(to->textureStack[j].top, from->textureStack[j].top))
1062 {
1063 diff_api.MatrixMode(GL_TEXTURE);
1064
1065 if (fd > td)
1066 {
1067 for (i = td; i < fd; i++)
1068 {
1069 diff_api.PopMatrix();
1070 }
1071 fd = td;
1072 }
1073
1074 diff_api.ActiveTextureARB( j + GL_TEXTURE0_ARB );
1075 for (i = fd; i <= td; i++)
1076 {
1077 LOADMATRIX(to->textureStack[j].stack + i);
1078 FILLDIRTY(t->textureMatrix);
1079 FILLDIRTY(t->dirty);
1080
1081 /* Don't want to push on the current matrix */
1082 if (i != to->textureStack[j].depth)
1083 diff_api.PushMatrix();
1084 }
1085 }
1086 }
1087 /* Since we were mucking with the active texture unit above set it to the
1088 * proper value now.
1089 */
1090 diff_api.ActiveTextureARB(GL_TEXTURE0_ARB + toCtx->texture.curTextureUnit);
1091 CLEARDIRTY(t->textureMatrix, nbitID);
1092 }
1093
1094 /* Color matrix */
1095 if ( (from->colorStack.depth != to->colorStack.depth) ||
1096 CHECKDIRTY(t->colorMatrix, bitID) )
1097 {
1098 GLuint td = to->colorStack.depth;
1099 GLuint fd = from->colorStack.depth;
1100 if (td != fd || !crMatrixIsEqual(to->colorStack.top, from->colorStack.top))
1101 {
1102 diff_api.MatrixMode(GL_COLOR);
1103
1104 if (fd > td)
1105 {
1106 for (i = td; i < fd; i++)
1107 {
1108 diff_api.PopMatrix();
1109 }
1110 fd = td;
1111 }
1112
1113 for (i = fd; i <= td; i++)
1114 {
1115 LOADMATRIX(to->colorStack.stack + i);
1116 FILLDIRTY(t->colorMatrix);
1117 FILLDIRTY(t->dirty);
1118
1119 /* Don't want to push on the current matrix */
1120 if (i != to->colorStack.depth)
1121 diff_api.PushMatrix();
1122 }
1123 }
1124 CLEARDIRTY(t->colorMatrix, nbitID);
1125 }
1126
1127 to->modelViewProjectionValid = 0;
1128 CLEARDIRTY(t->dirty, nbitID);
1129
1130 /* Since we were mucking with the current matrix above
1131 * set it to the proper value now.
1132 */
1133 diff_api.MatrixMode(to->matrixMode);
1134
1135 /* sanity tests */
1136 CRASSERT(from->modelViewStack.top == from->modelViewStack.stack + from->modelViewStack.depth);
1137 CRASSERT(from->projectionStack.top == from->projectionStack.stack + from->projectionStack.depth);
1138
1139}
1140
1141void
1142crStateTransformDiff( CRTransformBits *t, CRbitvalue *bitID,
1143 CRContext *fromCtx, CRContext *toCtx )
1144{
1145 const GLuint maxTextureUnits = toCtx->limits.maxTextureUnits;
1146 CRTransformState *from = &(fromCtx->transform);
1147 CRTransformState *to = &(toCtx->transform);
1148 CRTextureState *textureFrom = &(fromCtx->texture);
1149 GLuint i, j;
1150 unsigned int checktex = 0;
1151 CRbitvalue nbitID[CR_MAX_BITARRAY];
1152
1153 for (j=0;j<CR_MAX_BITARRAY;j++)
1154 nbitID[j] = ~bitID[j];
1155
1156 if (CHECKDIRTY(t->enable, bitID)) {
1157 glAble able[2];
1158 able[0] = diff_api.Disable;
1159 able[1] = diff_api.Enable;
1160 for (i=0; i<CR_MAX_CLIP_PLANES; i++) {
1161 if (from->clip[i] != to->clip[i]) {
1162 if (to->clip[i] == GL_TRUE)
1163 diff_api.Enable(GL_CLIP_PLANE0 + i);
1164 else
1165 diff_api.Disable(GL_CLIP_PLANE0 + i);
1166 from->clip[i] = to->clip[i];
1167 }
1168 }
1169 if (from->normalize != to->normalize) {
1170 if (to->normalize == GL_TRUE)
1171 diff_api.Enable(GL_NORMALIZE);
1172 else
1173 diff_api.Disable(GL_NORMALIZE);
1174 from->normalize = to->normalize;
1175 }
1176#ifdef CR_OPENGL_VERSION_1_2
1177 if (from->rescaleNormals != to->rescaleNormals) {
1178 able[to->rescaleNormals](GL_RESCALE_NORMAL);
1179 from->rescaleNormals = to->rescaleNormals;
1180 }
1181#else
1182 (void) able;
1183#endif
1184#ifdef CR_IBM_rasterpos_clip
1185 if (from->rasterPositionUnclipped != to->rasterPositionUnclipped) {
1186 able[to->rasterPositionUnclipped](GL_RASTER_POSITION_UNCLIPPED_IBM);
1187 from->rasterPositionUnclipped = to->rasterPositionUnclipped;
1188 }
1189#endif
1190
1191 CLEARDIRTY(t->enable, nbitID);
1192 }
1193
1194 if (CHECKDIRTY(t->clipPlane, bitID)) {
1195 if (from->matrixMode != GL_MODELVIEW) {
1196 diff_api.MatrixMode(GL_MODELVIEW);
1197 from->matrixMode = GL_MODELVIEW;
1198 }
1199 diff_api.PushMatrix();
1200 diff_api.LoadIdentity();
1201 for (i=0; i<CR_MAX_CLIP_PLANES; i++) {
1202 if (from->clipPlane[i].x != to->clipPlane[i].x ||
1203 from->clipPlane[i].y != to->clipPlane[i].y ||
1204 from->clipPlane[i].z != to->clipPlane[i].z ||
1205 from->clipPlane[i].w != to->clipPlane[i].w) {
1206
1207 GLdouble cp[4];
1208 cp[0] = to->clipPlane[i].x;
1209 cp[1] = to->clipPlane[i].y;
1210 cp[2] = to->clipPlane[i].z;
1211 cp[3] = to->clipPlane[i].w;
1212
1213 diff_api.ClipPlane(GL_CLIP_PLANE0 + i, (const GLdouble *)(cp));
1214 from->clipPlane[i] = to->clipPlane[i];
1215 }
1216 }
1217 diff_api.PopMatrix();
1218 CLEARDIRTY(t->clipPlane, nbitID);
1219 }
1220
1221 /* If the matrix stack depths don't match when we're
1222 * updating the context - we can update the wrong matrix
1223 * and get some lovely effects!!
1224 * So we troll each depth list here and Pop & Push the matrix stack
1225 * to bring it right up to date before checking the current
1226 * matrix.
1227 *
1228 * - Alan H.
1229 */
1230 if ( (from->modelViewStack.depth != to->modelViewStack.depth) ||
1231 CHECKDIRTY(t->modelviewMatrix, bitID) )
1232 {
1233 if (from->matrixMode != GL_MODELVIEW) {
1234 diff_api.MatrixMode(GL_MODELVIEW);
1235 from->matrixMode = GL_MODELVIEW;
1236 }
1237
1238 if (from->modelViewStack.depth > to->modelViewStack.depth)
1239 {
1240 for (i = to->modelViewStack.depth; i < from->modelViewStack.depth; i++)
1241 {
1242 diff_api.PopMatrix();
1243 }
1244
1245 from->modelViewStack.depth = to->modelViewStack.depth;
1246 }
1247
1248 for (i = from->modelViewStack.depth; i <= to->modelViewStack.depth; i++)
1249 {
1250 LOADMATRIX(to->modelViewStack.stack + i);
1251 from->modelViewStack.stack[i] = to->modelViewStack.stack[i];
1252
1253 /* Don't want to push on the current matrix */
1254 if (i != to->modelViewStack.depth)
1255 diff_api.PushMatrix();
1256 }
1257 from->modelViewStack.depth = to->modelViewStack.depth;
1258 from->modelViewStack.top = from->modelViewStack.stack + from->modelViewStack.depth;
1259
1260 CLEARDIRTY(t->modelviewMatrix, nbitID);
1261 }
1262
1263 /* Projection matrix */
1264 if ( (from->projectionStack.depth != to->projectionStack.depth) ||
1265 CHECKDIRTY(t->projectionMatrix, bitID) )
1266 {
1267 if (from->matrixMode != GL_PROJECTION) {
1268 diff_api.MatrixMode(GL_PROJECTION);
1269 from->matrixMode = GL_PROJECTION;
1270 }
1271
1272 if (from->projectionStack.depth > to->projectionStack.depth)
1273 {
1274 for (i = to->projectionStack.depth; i < from->projectionStack.depth; i++)
1275 {
1276 diff_api.PopMatrix();
1277 }
1278
1279 from->projectionStack.depth = to->projectionStack.depth;
1280 }
1281
1282 for (i = from->projectionStack.depth; i <= to->projectionStack.depth; i++)
1283 {
1284 LOADMATRIX(to->projectionStack.stack + i);
1285 from->projectionStack.stack[i] = to->projectionStack.stack[i];
1286
1287 /* Don't want to push on the current matrix */
1288 if (i != to->projectionStack.depth)
1289 diff_api.PushMatrix();
1290 }
1291 from->projectionStack.depth = to->projectionStack.depth;
1292 from->projectionStack.top = from->projectionStack.stack + from->projectionStack.depth;
1293
1294 CLEARDIRTY(t->projectionMatrix, nbitID);
1295 }
1296
1297 /* Texture matrices */
1298 for (i = 0 ; i < maxTextureUnits ; i++)
1299 if (from->textureStack[i].depth != to->textureStack[i].depth)
1300 checktex = 1;
1301
1302 if (checktex || CHECKDIRTY(t->textureMatrix, bitID))
1303 {
1304 if (from->matrixMode != GL_TEXTURE) {
1305 diff_api.MatrixMode(GL_TEXTURE);
1306 from->matrixMode = GL_TEXTURE;
1307 }
1308 for (j = 0 ; j < maxTextureUnits; j++)
1309 {
1310 if (from->textureStack[j].depth > to->textureStack[j].depth)
1311 {
1312 if (textureFrom->curTextureUnit != j) {
1313 diff_api.ActiveTextureARB( j + GL_TEXTURE0_ARB );
1314 textureFrom->curTextureUnit = j;
1315 }
1316 for (i = to->textureStack[j].depth; i < from->textureStack[j].depth; i++)
1317 {
1318 diff_api.PopMatrix();
1319 }
1320
1321 from->textureStack[j].depth = to->textureStack[j].depth;
1322 }
1323
1324 for (i = from->textureStack[j].depth; i <= to->textureStack[j].depth; i++)
1325 {
1326 if (textureFrom->curTextureUnit != j) {
1327 diff_api.ActiveTextureARB( j + GL_TEXTURE0_ARB );
1328 textureFrom->curTextureUnit = j;
1329 }
1330 LOADMATRIX(to->textureStack[j].stack + i);
1331 from->textureStack[j].stack[i] = to->textureStack[j].stack[i];
1332
1333 /* Don't want to push on the current matrix */
1334 if (i != to->textureStack[j].depth)
1335 diff_api.PushMatrix();
1336 }
1337 from->textureStack[j].depth = to->textureStack[j].depth;
1338 from->textureStack[j].top = from->textureStack[j].stack + from->textureStack[j].depth;
1339 }
1340 CLEARDIRTY(t->textureMatrix, nbitID);
1341
1342 /* Restore proper active texture unit */
1343 diff_api.ActiveTextureARB(GL_TEXTURE0_ARB + toCtx->texture.curTextureUnit);
1344 }
1345
1346 /* Color matrix */
1347 if ( (from->colorStack.depth != to->colorStack.depth) ||
1348 CHECKDIRTY(t->colorMatrix, bitID) )
1349 {
1350 if (from->matrixMode != GL_COLOR) {
1351 diff_api.MatrixMode(GL_COLOR);
1352 from->matrixMode = GL_COLOR;
1353 }
1354
1355 if (from->colorStack.depth > to->colorStack.depth)
1356 {
1357 for (i = to->colorStack.depth; i < from->colorStack.depth; i++)
1358 {
1359 diff_api.PopMatrix();
1360 }
1361
1362 from->colorStack.depth = to->colorStack.depth;
1363 }
1364
1365 for (i = to->colorStack.depth; i <= to->colorStack.depth; i++)
1366 {
1367 LOADMATRIX(to->colorStack.stack + i);
1368 from->colorStack.stack[i] = to->colorStack.stack[i];
1369
1370 /* Don't want to push on the current matrix */
1371 if (i != to->colorStack.depth)
1372 diff_api.PushMatrix();
1373 }
1374 from->colorStack.depth = to->colorStack.depth;
1375 from->colorStack.top = from->colorStack.stack + from->colorStack.depth;
1376
1377 CLEARDIRTY(t->colorMatrix, nbitID);
1378 }
1379
1380 to->modelViewProjectionValid = 0;
1381 CLEARDIRTY(t->dirty, nbitID);
1382
1383 /* update MatrixMode now */
1384 if (from->matrixMode != to->matrixMode) {
1385 diff_api.MatrixMode(to->matrixMode);
1386 from->matrixMode = to->matrixMode;
1387 }
1388
1389 /* sanity tests */
1390 CRASSERT(from->modelViewStack.top == from->modelViewStack.stack + from->modelViewStack.depth);
1391 CRASSERT(from->projectionStack.top == from->projectionStack.stack + from->projectionStack.depth);
1392}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette