VirtualBox

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

Last change on this file since 78493 was 78375, checked in by vboxsync, 6 years ago

Additions/common/crOpengl,GuestHost/OpenGL,HostServices/SharedOpenGL: Eliminate all global variables from the state tracker library (state_tracker) in preparation of the SPU DLL merging, bugref:9435

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 45.3 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(PCRStateTracker pState, 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 pState->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 pState->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(ctx->pStateTracker);
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 (PCRStateTracker pState, GLenum plane, const GLdouble *equation)
218{
219 CRContext *g = GetCurrentContext(pState);
220 CRTransformState *t = &g->transform;
221 CRStateBits *sb = GetCurrentBits(pState);
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(pState, __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(pState, __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(PCRStateTracker pState, GLenum e)
257{
258 CRContext *g = GetCurrentContext(pState);
259 CRTransformState *t = &(g->transform);
260 CRTextureState *tex = &(g->texture);
261 CRStateBits *sb = GetCurrentBits(pState);
262 CRTransformBits *tb = &(sb->transform);
263
264 if (g->current.inBeginEnd)
265 {
266 crStateError(pState, __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(pState, __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(pState, __LINE__, __FILE__, GL_INVALID_ENUM, "Invalid matrix mode: %d", e);
332 return;
333 }
334 break;
335 default:
336 crStateError(pState, __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(PCRStateTracker pState)
346{
347 CRContext *g = GetCurrentContext(pState);
348 CRTransformState *t = &(g->transform);
349 CRStateBits *sb = GetCurrentBits(pState);
350 CRTransformBits *tb = &(sb->transform);
351
352 if (g->current.inBeginEnd)
353 {
354 crStateError(pState, __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(PCRStateTracker pState)
369{
370 CRContext *g = GetCurrentContext(pState);
371 CRTransformState *t = &g->transform;
372 CRStateBits *sb = GetCurrentBits(pState);
373 CRTransformBits *tb = &(sb->transform);
374
375 if (g->current.inBeginEnd)
376 {
377 crStateError(pState, __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(pState, __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(PCRStateTracker pState)
401{
402 CRContext *g = GetCurrentContext(pState);
403 CRTransformState *t = &g->transform;
404 CRStateBits *sb = GetCurrentBits(pState);
405 CRTransformBits *tb = &(sb->transform);
406
407 if (g->current.inBeginEnd)
408 {
409 crStateError(pState, __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(pState, __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(PCRStateTracker pState, const CRmatrix *m)
436{
437 CRContext *g = GetCurrentContext(pState);
438 CRTransformState *t = &(g->transform);
439 CRStateBits *sb = GetCurrentBits(pState);
440 CRTransformBits *tb = &(sb->transform);
441
442 if (g->current.inBeginEnd)
443 {
444 crStateError(pState, __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(PCRStateTracker pState, const GLfloat *m1)
461{
462 CRContext *g = GetCurrentContext(pState);
463 CRTransformState *t = &(g->transform);
464 CRStateBits *sb = GetCurrentBits(pState);
465 CRTransformBits *tb = &(sb->transform);
466
467 if (g->current.inBeginEnd)
468 {
469 crStateError(pState, __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(PCRStateTracker pState, const GLdouble *m1)
484{
485 CRContext *g = GetCurrentContext(pState);
486 CRTransformState *t = &(g->transform);
487 CRStateBits *sb = GetCurrentBits(pState);
488 CRTransformBits *tb = &(sb->transform);
489
490 if (g->current.inBeginEnd)
491 {
492 crStateError(pState, __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(PCRStateTracker pState, const GLfloat *m1)
507{
508 GLfloat tm[16];
509 if (!m1) return;
510 _math_transposef(tm, m1);
511 crStateLoadMatrixf(pState, tm);
512}
513
514void STATE_APIENTRY crStateLoadTransposeMatrixdARB(PCRStateTracker pState, const GLdouble *m1)
515{
516 GLdouble tm[16];
517 if (!m1) return;
518 _math_transposed(tm, m1);
519 crStateLoadMatrixd(pState, 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(PCRStateTracker pState, const GLfloat *m1)
530{
531 CRContext *g = GetCurrentContext(pState);
532 CRTransformState *t = &(g->transform);
533 CRStateBits *sb = GetCurrentBits(pState);
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(pState, __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(PCRStateTracker pState, const GLdouble *m1)
602{
603 CRContext *g = GetCurrentContext(pState);
604 CRTransformState *t = &(g->transform);
605 CRStateBits *sb = GetCurrentBits(pState);
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(pState, __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(PCRStateTracker pState, const GLfloat *m1)
673{
674 GLfloat tm[16];
675 if (!m1) return;
676 _math_transposef(tm, m1);
677 crStateMultMatrixf(pState, tm);
678}
679
680void STATE_APIENTRY crStateMultTransposeMatrixdARB(PCRStateTracker pState, const GLdouble *m1)
681{
682 GLdouble tm[16];
683 if (!m1) return;
684 _math_transposed(tm, m1);
685 crStateMultMatrixd(pState, tm);
686}
687
688void STATE_APIENTRY crStateTranslatef(PCRStateTracker pState, GLfloat x_arg, GLfloat y_arg, GLfloat z_arg)
689{
690 CRContext *g = GetCurrentContext(pState);
691 CRTransformState *t = &(g->transform);
692 CRStateBits *sb = GetCurrentBits(pState);
693 CRTransformBits *tb = &(sb->transform);
694
695 if (g->current.inBeginEnd)
696 {
697 crStateError(pState, __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(PCRStateTracker pState, GLdouble x_arg, GLdouble y_arg, GLdouble z_arg)
712{
713 CRContext *g = GetCurrentContext(pState);
714 CRTransformState *t = &(g->transform);
715 CRStateBits *sb = GetCurrentBits(pState);
716 CRTransformBits *tb = &(sb->transform);
717
718 if (g->current.inBeginEnd)
719 {
720 crStateError(pState, __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(PCRStateTracker pState, GLfloat ang, GLfloat x, GLfloat y, GLfloat z)
735{
736 CRContext *g = GetCurrentContext(pState);
737 CRTransformState *t = &(g->transform);
738 CRStateBits *sb = GetCurrentBits(pState);
739 CRTransformBits *tb = &(sb->transform);
740
741 if (g->current.inBeginEnd)
742 {
743 crStateError(pState, __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(PCRStateTracker pState, GLdouble ang, GLdouble x, GLdouble y, GLdouble z)
757{
758 CRContext *g = GetCurrentContext(pState);
759 CRTransformState *t = &(g->transform);
760 CRStateBits *sb = GetCurrentBits(pState);
761 CRTransformBits *tb = &(sb->transform);
762
763 if (g->current.inBeginEnd)
764 {
765 crStateError(pState, __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 (PCRStateTracker pState, GLfloat x_arg, GLfloat y_arg, GLfloat z_arg)
779{
780 CRContext *g = GetCurrentContext(pState);
781 CRTransformState *t = &(g->transform);
782 CRStateBits *sb = GetCurrentBits(pState);
783 CRTransformBits *tb = &(sb->transform);
784
785 if (g->current.inBeginEnd)
786 {
787 crStateError(pState, __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 (PCRStateTracker pState, GLdouble x_arg, GLdouble y_arg, GLdouble z_arg)
801{
802 CRContext *g = GetCurrentContext(pState);
803 CRTransformState *t = &(g->transform);
804 CRStateBits *sb = GetCurrentBits(pState);
805 CRTransformBits *tb = &(sb->transform);
806
807 if (g->current.inBeginEnd)
808 {
809 crStateError(pState, __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(PCRStateTracker pState, GLdouble left, GLdouble right,
823 GLdouble bottom, GLdouble top,
824 GLdouble zNear, GLdouble zFar)
825{
826 CRContext *g = GetCurrentContext(pState);
827 CRTransformState *t = &(g->transform);
828 CRStateBits *sb = GetCurrentBits(pState);
829 CRTransformBits *tb = &(sb->transform);
830
831 if (g->current.inBeginEnd)
832 {
833 crStateError(pState, __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(PCRStateTracker pState, GLdouble left, GLdouble right,
847 GLdouble bottom, GLdouble top,
848 GLdouble zNear, GLdouble zFar)
849{
850 CRContext *g = GetCurrentContext(pState);
851 CRTransformState *t = &(g->transform);
852 CRStateBits *sb = GetCurrentBits(pState);
853 CRTransformBits *tb = &(sb->transform);
854
855 if (g->current.inBeginEnd)
856 {
857 crStateError(pState, __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(PCRStateTracker pState, GLenum plane, GLdouble *equation)
871{
872 CRContext *g = GetCurrentContext(pState);
873 CRTransformState *t = &g->transform;
874 unsigned int i;
875
876 if (g->current.inBeginEnd)
877 {
878 crStateError(pState, __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(pState, __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 PCRStateTracker pState = fromCtx->pStateTracker;
901 const GLuint maxTextureUnits = toCtx->limits.maxTextureUnits;
902 CRTransformState *from = &(fromCtx->transform);
903 CRTransformState *to = &(toCtx->transform);
904 GLuint i, j;
905 unsigned int checktex = 0;
906 CRbitvalue nbitID[CR_MAX_BITARRAY];
907
908 CRASSERT(fromCtx->pStateTracker == toCtx->pStateTracker);
909
910 for (j=0;j<CR_MAX_BITARRAY;j++)
911 nbitID[j] = ~bitID[j];
912
913 if (CHECKDIRTY(t->enable, bitID))
914 {
915 glAble able[2];
916 able[0] = pState->diff_api.Disable;
917 able[1] = pState->diff_api.Enable;
918 if (from->normalize != to->normalize) {
919 if (to->normalize == GL_TRUE)
920 pState->diff_api.Enable(GL_NORMALIZE);
921 else
922 pState->diff_api.Disable(GL_NORMALIZE);
923 FILLDIRTY(t->enable);
924 FILLDIRTY(t->dirty);
925 }
926#ifdef CR_OPENGL_VERSION_1_2
927 if (from->rescaleNormals != to->rescaleNormals)
928 {
929 able[to->rescaleNormals](GL_RESCALE_NORMAL);
930 FILLDIRTY(t->enable);
931 FILLDIRTY(t->dirty);
932 }
933#else
934 (void) able;
935#endif
936#ifdef CR_IBM_rasterpos_clip
937 if (from->rasterPositionUnclipped != to->rasterPositionUnclipped)
938 {
939 able[to->rasterPositionUnclipped](GL_RASTER_POSITION_UNCLIPPED_IBM);
940 FILLDIRTY(t->enable);
941 FILLDIRTY(t->dirty);
942 }
943#endif
944 CLEARDIRTY(t->enable, nbitID);
945 }
946
947 if (CHECKDIRTY(t->clipPlane, bitID)) {
948 pState->diff_api.MatrixMode(GL_MODELVIEW);
949 pState->diff_api.PushMatrix();
950 pState->diff_api.LoadIdentity();
951 for (i=0; i<CR_MAX_CLIP_PLANES; i++) {
952 if (from->clipPlane[i].x != to->clipPlane[i].x ||
953 from->clipPlane[i].y != to->clipPlane[i].y ||
954 from->clipPlane[i].z != to->clipPlane[i].z ||
955 from->clipPlane[i].w != to->clipPlane[i].w) {
956
957 GLdouble cp[4];
958 cp[0] = to->clipPlane[i].x;
959 cp[1] = to->clipPlane[i].y;
960 cp[2] = to->clipPlane[i].z;
961 cp[3] = to->clipPlane[i].w;
962
963 pState->diff_api.ClipPlane(GL_CLIP_PLANE0 + i, (const GLdouble *)(cp));
964
965 FILLDIRTY(t->clipPlane);
966 FILLDIRTY(t->dirty);
967 }
968 }
969 pState->diff_api.PopMatrix();
970 CLEARDIRTY(t->clipPlane, nbitID);
971 }
972
973 /* If the matrix stack depths don't match when we're
974 * updating the context - we can update the wrong matrix
975 * and get some lovely effects!!
976 * So we troll each depth list here and Pop & Push the matrix stack
977 * to bring it right up to date before checking the current
978 * matrix.
979 *
980 * - Alan H.
981 */
982 if ( (from->modelViewStack.depth != to->modelViewStack.depth) ||
983 CHECKDIRTY(t->modelviewMatrix, bitID) )
984 {
985 GLuint td = to->modelViewStack.depth;
986 GLuint fd = from->modelViewStack.depth;
987
988 if (td != fd ||
989 !crMatrixIsEqual(to->modelViewStack.top, from->modelViewStack.top))
990 {
991 pState->diff_api.MatrixMode(GL_MODELVIEW);
992
993 if (fd > td)
994 {
995 for (i = td; i < fd; i++)
996 {
997 pState->diff_api.PopMatrix();
998 }
999 fd = td;
1000 }
1001
1002 for (i = fd; i <= td; i++)
1003 {
1004 LOADMATRIX(pState, to->modelViewStack.stack + i);
1005 FILLDIRTY(t->modelviewMatrix);
1006 FILLDIRTY(t->dirty);
1007
1008 /* Don't want to push on the current matrix */
1009 if (i != to->modelViewStack.depth)
1010 pState->diff_api.PushMatrix();
1011 }
1012 }
1013 CLEARDIRTY(t->modelviewMatrix, nbitID);
1014 }
1015
1016 /* Projection matrix */
1017 if ( (from->projectionStack.depth != to->projectionStack.depth) ||
1018 CHECKDIRTY(t->projectionMatrix, bitID) )
1019 {
1020 GLuint td = to->projectionStack.depth;
1021 GLuint fd = from->projectionStack.depth;
1022
1023 if (td != fd ||
1024 !crMatrixIsEqual(to->projectionStack.top, from->projectionStack.top)) {
1025
1026 pState->diff_api.MatrixMode(GL_PROJECTION);
1027
1028 if (fd > td)
1029 {
1030 for (i = td; i < fd; i++)
1031 {
1032 pState->diff_api.PopMatrix();
1033 }
1034 fd = td;
1035 }
1036
1037 for (i = fd; i <= td; i++)
1038 {
1039 LOADMATRIX(pState, to->projectionStack.stack + i);
1040 FILLDIRTY(t->projectionMatrix);
1041 FILLDIRTY(t->dirty);
1042
1043 /* Don't want to push on the current matrix */
1044 if (i != to->projectionStack.depth)
1045 pState->diff_api.PushMatrix();
1046 }
1047 }
1048 CLEARDIRTY(t->projectionMatrix, nbitID);
1049 }
1050
1051 /* Texture matrices */
1052 for (i = 0 ; i < maxTextureUnits ; i++)
1053 if (from->textureStack[i].depth != to->textureStack[i].depth)
1054 checktex = 1;
1055
1056 if ( checktex || CHECKDIRTY(t->textureMatrix, bitID) )
1057 {
1058 for (j = 0 ; j < maxTextureUnits ; j++)
1059 {
1060 GLuint td = to->textureStack[j].depth;
1061 GLuint fd = from->textureStack[j].depth;
1062
1063 if (td != fd ||
1064 !crMatrixIsEqual(to->textureStack[j].top, from->textureStack[j].top))
1065 {
1066 pState->diff_api.MatrixMode(GL_TEXTURE);
1067
1068 if (fd > td)
1069 {
1070 for (i = td; i < fd; i++)
1071 {
1072 pState->diff_api.PopMatrix();
1073 }
1074 fd = td;
1075 }
1076
1077 pState->diff_api.ActiveTextureARB( j + GL_TEXTURE0_ARB );
1078 for (i = fd; i <= td; i++)
1079 {
1080 LOADMATRIX(pState, to->textureStack[j].stack + i);
1081 FILLDIRTY(t->textureMatrix);
1082 FILLDIRTY(t->dirty);
1083
1084 /* Don't want to push on the current matrix */
1085 if (i != to->textureStack[j].depth)
1086 pState->diff_api.PushMatrix();
1087 }
1088 }
1089 }
1090 /* Since we were mucking with the active texture unit above set it to the
1091 * proper value now.
1092 */
1093 pState->diff_api.ActiveTextureARB(GL_TEXTURE0_ARB + toCtx->texture.curTextureUnit);
1094 CLEARDIRTY(t->textureMatrix, nbitID);
1095 }
1096
1097 /* Color matrix */
1098 if ( (from->colorStack.depth != to->colorStack.depth) ||
1099 CHECKDIRTY(t->colorMatrix, bitID) )
1100 {
1101 GLuint td = to->colorStack.depth;
1102 GLuint fd = from->colorStack.depth;
1103 if (td != fd || !crMatrixIsEqual(to->colorStack.top, from->colorStack.top))
1104 {
1105 pState->diff_api.MatrixMode(GL_COLOR);
1106
1107 if (fd > td)
1108 {
1109 for (i = td; i < fd; i++)
1110 {
1111 pState->diff_api.PopMatrix();
1112 }
1113 fd = td;
1114 }
1115
1116 for (i = fd; i <= td; i++)
1117 {
1118 LOADMATRIX(pState, to->colorStack.stack + i);
1119 FILLDIRTY(t->colorMatrix);
1120 FILLDIRTY(t->dirty);
1121
1122 /* Don't want to push on the current matrix */
1123 if (i != to->colorStack.depth)
1124 pState->diff_api.PushMatrix();
1125 }
1126 }
1127 CLEARDIRTY(t->colorMatrix, nbitID);
1128 }
1129
1130 to->modelViewProjectionValid = 0;
1131 CLEARDIRTY(t->dirty, nbitID);
1132
1133 /* Since we were mucking with the current matrix above
1134 * set it to the proper value now.
1135 */
1136 pState->diff_api.MatrixMode(to->matrixMode);
1137
1138 /* sanity tests */
1139 CRASSERT(from->modelViewStack.top == from->modelViewStack.stack + from->modelViewStack.depth);
1140 CRASSERT(from->projectionStack.top == from->projectionStack.stack + from->projectionStack.depth);
1141
1142}
1143
1144void
1145crStateTransformDiff( CRTransformBits *t, CRbitvalue *bitID,
1146 CRContext *fromCtx, CRContext *toCtx )
1147{
1148 PCRStateTracker pState = fromCtx->pStateTracker;
1149 const GLuint maxTextureUnits = toCtx->limits.maxTextureUnits;
1150 CRTransformState *from = &(fromCtx->transform);
1151 CRTransformState *to = &(toCtx->transform);
1152 CRTextureState *textureFrom = &(fromCtx->texture);
1153 GLuint i, j;
1154 unsigned int checktex = 0;
1155 CRbitvalue nbitID[CR_MAX_BITARRAY];
1156
1157 CRASSERT(fromCtx->pStateTracker == toCtx->pStateTracker);
1158
1159 for (j=0;j<CR_MAX_BITARRAY;j++)
1160 nbitID[j] = ~bitID[j];
1161
1162 if (CHECKDIRTY(t->enable, bitID)) {
1163 glAble able[2];
1164 able[0] = pState->diff_api.Disable;
1165 able[1] = pState->diff_api.Enable;
1166 for (i=0; i<CR_MAX_CLIP_PLANES; i++) {
1167 if (from->clip[i] != to->clip[i]) {
1168 if (to->clip[i] == GL_TRUE)
1169 pState->diff_api.Enable(GL_CLIP_PLANE0 + i);
1170 else
1171 pState->diff_api.Disable(GL_CLIP_PLANE0 + i);
1172 from->clip[i] = to->clip[i];
1173 }
1174 }
1175 if (from->normalize != to->normalize) {
1176 if (to->normalize == GL_TRUE)
1177 pState->diff_api.Enable(GL_NORMALIZE);
1178 else
1179 pState->diff_api.Disable(GL_NORMALIZE);
1180 from->normalize = to->normalize;
1181 }
1182#ifdef CR_OPENGL_VERSION_1_2
1183 if (from->rescaleNormals != to->rescaleNormals) {
1184 able[to->rescaleNormals](GL_RESCALE_NORMAL);
1185 from->rescaleNormals = to->rescaleNormals;
1186 }
1187#else
1188 (void) able;
1189#endif
1190#ifdef CR_IBM_rasterpos_clip
1191 if (from->rasterPositionUnclipped != to->rasterPositionUnclipped) {
1192 able[to->rasterPositionUnclipped](GL_RASTER_POSITION_UNCLIPPED_IBM);
1193 from->rasterPositionUnclipped = to->rasterPositionUnclipped;
1194 }
1195#endif
1196
1197 CLEARDIRTY(t->enable, nbitID);
1198 }
1199
1200 if (CHECKDIRTY(t->clipPlane, bitID)) {
1201 if (from->matrixMode != GL_MODELVIEW) {
1202 pState->diff_api.MatrixMode(GL_MODELVIEW);
1203 from->matrixMode = GL_MODELVIEW;
1204 }
1205 pState->diff_api.PushMatrix();
1206 pState->diff_api.LoadIdentity();
1207 for (i=0; i<CR_MAX_CLIP_PLANES; i++) {
1208 if (from->clipPlane[i].x != to->clipPlane[i].x ||
1209 from->clipPlane[i].y != to->clipPlane[i].y ||
1210 from->clipPlane[i].z != to->clipPlane[i].z ||
1211 from->clipPlane[i].w != to->clipPlane[i].w) {
1212
1213 GLdouble cp[4];
1214 cp[0] = to->clipPlane[i].x;
1215 cp[1] = to->clipPlane[i].y;
1216 cp[2] = to->clipPlane[i].z;
1217 cp[3] = to->clipPlane[i].w;
1218
1219 pState->diff_api.ClipPlane(GL_CLIP_PLANE0 + i, (const GLdouble *)(cp));
1220 from->clipPlane[i] = to->clipPlane[i];
1221 }
1222 }
1223 pState->diff_api.PopMatrix();
1224 CLEARDIRTY(t->clipPlane, nbitID);
1225 }
1226
1227 /* If the matrix stack depths don't match when we're
1228 * updating the context - we can update the wrong matrix
1229 * and get some lovely effects!!
1230 * So we troll each depth list here and Pop & Push the matrix stack
1231 * to bring it right up to date before checking the current
1232 * matrix.
1233 *
1234 * - Alan H.
1235 */
1236 if ( (from->modelViewStack.depth != to->modelViewStack.depth) ||
1237 CHECKDIRTY(t->modelviewMatrix, bitID) )
1238 {
1239 if (from->matrixMode != GL_MODELVIEW) {
1240 pState->diff_api.MatrixMode(GL_MODELVIEW);
1241 from->matrixMode = GL_MODELVIEW;
1242 }
1243
1244 if (from->modelViewStack.depth > to->modelViewStack.depth)
1245 {
1246 for (i = to->modelViewStack.depth; i < from->modelViewStack.depth; i++)
1247 {
1248 pState->diff_api.PopMatrix();
1249 }
1250
1251 from->modelViewStack.depth = to->modelViewStack.depth;
1252 }
1253
1254 for (i = from->modelViewStack.depth; i <= to->modelViewStack.depth; i++)
1255 {
1256 LOADMATRIX(pState, to->modelViewStack.stack + i);
1257 from->modelViewStack.stack[i] = to->modelViewStack.stack[i];
1258
1259 /* Don't want to push on the current matrix */
1260 if (i != to->modelViewStack.depth)
1261 pState->diff_api.PushMatrix();
1262 }
1263 from->modelViewStack.depth = to->modelViewStack.depth;
1264 from->modelViewStack.top = from->modelViewStack.stack + from->modelViewStack.depth;
1265
1266 CLEARDIRTY(t->modelviewMatrix, nbitID);
1267 }
1268
1269 /* Projection matrix */
1270 if ( (from->projectionStack.depth != to->projectionStack.depth) ||
1271 CHECKDIRTY(t->projectionMatrix, bitID) )
1272 {
1273 if (from->matrixMode != GL_PROJECTION) {
1274 pState->diff_api.MatrixMode(GL_PROJECTION);
1275 from->matrixMode = GL_PROJECTION;
1276 }
1277
1278 if (from->projectionStack.depth > to->projectionStack.depth)
1279 {
1280 for (i = to->projectionStack.depth; i < from->projectionStack.depth; i++)
1281 {
1282 pState->diff_api.PopMatrix();
1283 }
1284
1285 from->projectionStack.depth = to->projectionStack.depth;
1286 }
1287
1288 for (i = from->projectionStack.depth; i <= to->projectionStack.depth; i++)
1289 {
1290 LOADMATRIX(pState, to->projectionStack.stack + i);
1291 from->projectionStack.stack[i] = to->projectionStack.stack[i];
1292
1293 /* Don't want to push on the current matrix */
1294 if (i != to->projectionStack.depth)
1295 pState->diff_api.PushMatrix();
1296 }
1297 from->projectionStack.depth = to->projectionStack.depth;
1298 from->projectionStack.top = from->projectionStack.stack + from->projectionStack.depth;
1299
1300 CLEARDIRTY(t->projectionMatrix, nbitID);
1301 }
1302
1303 /* Texture matrices */
1304 for (i = 0 ; i < maxTextureUnits ; i++)
1305 if (from->textureStack[i].depth != to->textureStack[i].depth)
1306 checktex = 1;
1307
1308 if (checktex || CHECKDIRTY(t->textureMatrix, bitID))
1309 {
1310 if (from->matrixMode != GL_TEXTURE) {
1311 pState->diff_api.MatrixMode(GL_TEXTURE);
1312 from->matrixMode = GL_TEXTURE;
1313 }
1314 for (j = 0 ; j < maxTextureUnits; j++)
1315 {
1316 if (from->textureStack[j].depth > to->textureStack[j].depth)
1317 {
1318 if (textureFrom->curTextureUnit != j) {
1319 pState->diff_api.ActiveTextureARB( j + GL_TEXTURE0_ARB );
1320 textureFrom->curTextureUnit = j;
1321 }
1322 for (i = to->textureStack[j].depth; i < from->textureStack[j].depth; i++)
1323 {
1324 pState->diff_api.PopMatrix();
1325 }
1326
1327 from->textureStack[j].depth = to->textureStack[j].depth;
1328 }
1329
1330 for (i = from->textureStack[j].depth; i <= to->textureStack[j].depth; i++)
1331 {
1332 if (textureFrom->curTextureUnit != j) {
1333 pState->diff_api.ActiveTextureARB( j + GL_TEXTURE0_ARB );
1334 textureFrom->curTextureUnit = j;
1335 }
1336 LOADMATRIX(pState, to->textureStack[j].stack + i);
1337 from->textureStack[j].stack[i] = to->textureStack[j].stack[i];
1338
1339 /* Don't want to push on the current matrix */
1340 if (i != to->textureStack[j].depth)
1341 pState->diff_api.PushMatrix();
1342 }
1343 from->textureStack[j].depth = to->textureStack[j].depth;
1344 from->textureStack[j].top = from->textureStack[j].stack + from->textureStack[j].depth;
1345 }
1346 CLEARDIRTY(t->textureMatrix, nbitID);
1347
1348 /* Restore proper active texture unit */
1349 pState->diff_api.ActiveTextureARB(GL_TEXTURE0_ARB + toCtx->texture.curTextureUnit);
1350 }
1351
1352 /* Color matrix */
1353 if ( (from->colorStack.depth != to->colorStack.depth) ||
1354 CHECKDIRTY(t->colorMatrix, bitID) )
1355 {
1356 if (from->matrixMode != GL_COLOR) {
1357 pState->diff_api.MatrixMode(GL_COLOR);
1358 from->matrixMode = GL_COLOR;
1359 }
1360
1361 if (from->colorStack.depth > to->colorStack.depth)
1362 {
1363 for (i = to->colorStack.depth; i < from->colorStack.depth; i++)
1364 {
1365 pState->diff_api.PopMatrix();
1366 }
1367
1368 from->colorStack.depth = to->colorStack.depth;
1369 }
1370
1371 for (i = to->colorStack.depth; i <= to->colorStack.depth; i++)
1372 {
1373 LOADMATRIX(pState, to->colorStack.stack + i);
1374 from->colorStack.stack[i] = to->colorStack.stack[i];
1375
1376 /* Don't want to push on the current matrix */
1377 if (i != to->colorStack.depth)
1378 pState->diff_api.PushMatrix();
1379 }
1380 from->colorStack.depth = to->colorStack.depth;
1381 from->colorStack.top = from->colorStack.stack + from->colorStack.depth;
1382
1383 CLEARDIRTY(t->colorMatrix, nbitID);
1384 }
1385
1386 to->modelViewProjectionValid = 0;
1387 CLEARDIRTY(t->dirty, nbitID);
1388
1389 /* update MatrixMode now */
1390 if (from->matrixMode != to->matrixMode) {
1391 pState->diff_api.MatrixMode(to->matrixMode);
1392 from->matrixMode = to->matrixMode;
1393 }
1394
1395 /* sanity tests */
1396 CRASSERT(from->modelViewStack.top == from->modelViewStack.stack + from->modelViewStack.depth);
1397 CRASSERT(from->projectionStack.top == from->projectionStack.stack + from->projectionStack.depth);
1398}
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