VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_stencil.c@ 62814

Last change on this file since 62814 was 62814, checked in by vboxsync, 9 years ago

GuestHost/OpenGL: warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 52.5 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 <stdio.h>
8#include "state.h"
9#include "state/cr_statetypes.h"
10#include "state_internals.h"
11
12
13static GLint crStateStencilBufferGetIdxAndCount(CRStencilState *s, GLenum face, GLint *pIdx, GLint *pBitsIdx)
14{
15 switch (face)
16 {
17 case GL_FRONT_AND_BACK:
18 *pIdx = 0;
19 *pBitsIdx = CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK;
20 return 2;
21 case GL_FRONT:
22 *pIdx = CRSTATE_STENCIL_BUFFER_ID_FRONT;
23 *pBitsIdx = CRSTATE_STENCIL_BUFFER_REF_ID_FRONT;
24 return 1;
25 case GL_BACK:
26 *pIdx = CRSTATE_STENCIL_BUFFER_ID_BACK;
27 *pBitsIdx = CRSTATE_STENCIL_BUFFER_REF_ID_BACK;
28 return 1;
29 case 0:
30 if (!s->stencilTwoSideEXT || s->activeStencilFace == GL_FRONT)
31 {
32 /* both front and back */
33 *pIdx = 0;
34 *pBitsIdx = CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK;
35 return 2;
36 }
37 *pIdx = CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK;
38 *pBitsIdx = CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK;
39 return 1;
40 default:
41 crStateError(__LINE__,__FILE__,GL_INVALID_ENUM, "crStateStencilBufferGetIdxAndCount");
42 return 0;
43 }
44#ifndef VBOX /* unreachable */
45 crError("should never be here!");
46 return 0;
47#endif
48}
49
50void crStateStencilBufferInit(CRStencilBufferState *s)
51{
52 s->func = GL_ALWAYS;
53 s->mask = 0xFFFFFFFF;
54 s->ref = 0;
55
56 s->fail = GL_KEEP;
57 s->passDepthFail = GL_KEEP;
58 s->passDepthPass = GL_KEEP;
59}
60
61static void crStateStencilBufferRefBitsInit(CRContext *ctx, CRStencilBufferRefBits *sb)
62{
63 RESET(sb->func, ctx->bitid);
64 RESET(sb->op, ctx->bitid);
65}
66
67void crStateStencilInit(CRContext *ctx)
68{
69 CRStencilState *s = &ctx->stencil;
70 CRStateBits *stateb = GetCurrentBits();
71 CRStencilBits *sb = &(stateb->stencil);
72 int i;
73
74 s->stencilTest = GL_FALSE;
75 RESET(sb->enable, ctx->bitid);
76
77 s->stencilTwoSideEXT = GL_FALSE;
78 RESET(sb->enableTwoSideEXT, ctx->bitid);
79
80 s->activeStencilFace = GL_FRONT;
81 RESET(sb->activeStencilFace, ctx->bitid);
82
83 s->clearValue = 0;
84 RESET(sb->clearValue, ctx->bitid);
85
86 s->writeMask = 0xFFFFFFFF;
87 RESET(sb->writeMask, ctx->bitid);
88
89 RESET(sb->dirty, ctx->bitid);
90
91 for (i = 0; i < CRSTATE_STENCIL_BUFFER_COUNT; ++i)
92 {
93 crStateStencilBufferInit(&s->buffers[i]);
94 }
95
96 for (i = 0; i < CRSTATE_STENCIL_BUFFER_REF_COUNT; ++i)
97 {
98 crStateStencilBufferRefBitsInit(ctx, &sb->bufferRefs[i]);
99 }
100}
101
102static void crStateStencilBufferFunc(CRContext *g, CRStencilBufferState *s, GLenum func, GLint ref, GLuint mask)
103{
104 s->func = func;
105 s->ref = ref;
106 s->mask = mask;
107}
108
109static void crStateStencilFuncPerform(GLenum face, GLenum func, GLint ref, GLuint mask)
110{
111 CRContext *g = GetCurrentContext();
112 CRStencilState *s = &(g->stencil);
113 CRStateBits *stateb = GetCurrentBits();
114 CRStencilBits *sb = &(stateb->stencil);
115 GLint idx, bitsIdx, count, i;
116
117
118 if (g->current.inBeginEnd)
119 {
120 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
121 "glStencilFunc called in begin/end");
122 return;
123 }
124
125 FLUSH();
126
127 if (func != GL_NEVER &&
128 func != GL_LESS &&
129 func != GL_LEQUAL &&
130 func != GL_GREATER &&
131 func != GL_GEQUAL &&
132 func != GL_EQUAL &&
133 func != GL_NOTEQUAL &&
134 func != GL_ALWAYS)
135 {
136 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
137 "glStencilFunc called with bogu func: %d", func);
138 return;
139 }
140
141 count = crStateStencilBufferGetIdxAndCount(s, face, &idx, &bitsIdx);
142 if (count)
143 {
144 for (i = idx; i < idx + count; ++i)
145 {
146 crStateStencilBufferFunc(g, &s->buffers[i], func, ref, mask);
147 }
148 DIRTY(sb->bufferRefs[bitsIdx].func, g->neg_bitid);
149
150 DIRTY(sb->dirty, g->neg_bitid);
151 }
152}
153
154void STATE_APIENTRY crStateStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
155{
156 if (!face)
157 {
158 /* crStateStencilFuncPerform accepts 0 value, while glStencilFuncSeparate does not,
159 * filter it out here */
160 crStateError(__LINE__,__FILE__,GL_INVALID_ENUM, "crStateStencilFuncSeparate");
161 return;
162 }
163 crStateStencilFuncPerform(face, func, ref, mask);
164}
165
166void STATE_APIENTRY crStateStencilFunc(GLenum func, GLint ref, GLuint mask)
167{
168 crStateStencilFuncPerform(0, func, ref, mask);
169}
170
171static void STATE_APIENTRY crStateStencilBufferOp (CRContext *g, CRStencilBufferState *s, GLenum fail, GLenum zfail, GLenum zpass)
172{
173 s->fail = fail;
174 s->passDepthFail = zfail;
175 s->passDepthPass = zpass;
176}
177
178static void crStateStencilOpPerform (GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
179{
180 CRContext *g = GetCurrentContext();
181 CRStencilState *s = &(g->stencil);
182 CRStateBits *stateb = GetCurrentBits();
183 CRStencilBits *sb = &(stateb->stencil);
184 GLint idx, bitsIdx, count, i;
185
186 if (g->current.inBeginEnd)
187 {
188 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
189 "glStencilOp called in begin/end");
190 return;
191 }
192
193 FLUSH();
194
195 switch (fail) {
196 case GL_KEEP:
197 case GL_ZERO:
198 case GL_REPLACE:
199 case GL_INCR:
200 case GL_DECR:
201 case GL_INVERT:
202#ifdef CR_EXT_stencil_wrap
203 case GL_INCR_WRAP_EXT:
204 case GL_DECR_WRAP_EXT:
205#endif
206 break;
207 default:
208 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
209 "glStencilOp called with bogus fail: %d", fail);
210 return;
211 }
212
213 switch (zfail) {
214 case GL_KEEP:
215 case GL_ZERO:
216 case GL_REPLACE:
217 case GL_INCR:
218 case GL_DECR:
219 case GL_INVERT:
220#ifdef CR_EXT_stencil_wrap
221 case GL_INCR_WRAP_EXT:
222 case GL_DECR_WRAP_EXT:
223#endif
224 break;
225 default:
226 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
227 "glStencilOp called with bogus zfail: %d", zfail);
228 return;
229 }
230
231 switch (zpass) {
232 case GL_KEEP:
233 case GL_ZERO:
234 case GL_REPLACE:
235 case GL_INCR:
236 case GL_DECR:
237 case GL_INVERT:
238#ifdef CR_EXT_stencil_wrap
239 case GL_INCR_WRAP_EXT:
240 case GL_DECR_WRAP_EXT:
241#endif
242 break;
243 default:
244 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
245 "glStencilOp called with bogus zpass: %d", zpass);
246 return;
247 }
248
249 count = crStateStencilBufferGetIdxAndCount(s, face, &idx, &bitsIdx);
250 if (count)
251 {
252 for (i = idx; i < idx + count; ++i)
253 {
254 crStateStencilBufferOp(g, &s->buffers[i], fail, zfail, zpass);
255 }
256
257 DIRTY(sb->bufferRefs[bitsIdx].op, g->neg_bitid);
258
259 DIRTY(sb->dirty, g->neg_bitid);
260 }
261}
262
263void STATE_APIENTRY crStateStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
264{
265 if (!face)
266 {
267 /* crStateStencilOpPerform accepts 0 value, while glStencilOpSeparate does not,
268 * filter it out here */
269 crStateError(__LINE__,__FILE__,GL_INVALID_ENUM, "crStateStencilOpSeparate");
270 return;
271 }
272 crStateStencilOpPerform (0, fail, zfail, zpass);
273}
274
275void STATE_APIENTRY crStateStencilOp (GLenum fail, GLenum zfail, GLenum zpass)
276{
277 crStateStencilOpPerform (0, fail, zfail, zpass);
278}
279
280void STATE_APIENTRY crStateClearStencil (GLint c)
281{
282 CRContext *g = GetCurrentContext();
283 CRStencilState *s = &(g->stencil);
284 CRStateBits *stateb = GetCurrentBits();
285 CRStencilBits *sb = &(stateb->stencil);
286
287 if (g->current.inBeginEnd)
288 {
289 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
290 "glClearStencil called in begin/end");
291 return;
292 }
293
294 FLUSH();
295
296 s->clearValue = c;
297
298 DIRTY(sb->clearValue, g->neg_bitid);
299 DIRTY(sb->dirty, g->neg_bitid);
300}
301
302void STATE_APIENTRY crStateStencilMask (GLuint mask)
303{
304 CRContext *g = GetCurrentContext();
305 CRStencilState *s = &(g->stencil);
306 CRStateBits *stateb = GetCurrentBits();
307 CRStencilBits *sb = &(stateb->stencil);
308
309 if (g->current.inBeginEnd)
310 {
311 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
312 "glStencilMask called in begin/end");
313 return;
314 }
315
316 FLUSH();
317
318 s->writeMask = mask;
319
320 DIRTY(sb->writeMask, g->neg_bitid);
321 DIRTY(sb->dirty, g->neg_bitid);
322}
323
324void STATE_APIENTRY crStateActiveStencilFaceEXT (GLenum face)
325{
326 CRContext *g = GetCurrentContext();
327 CRStencilState *s = &(g->stencil);
328 CRStateBits *stateb = GetCurrentBits();
329 CRStencilBits *sb = &(stateb->stencil);
330
331 switch (face)
332 {
333 case GL_FRONT:
334 case GL_BACK:
335 s->activeStencilFace = face;
336 break;
337 default:
338 crStateError(__LINE__,__FILE__,GL_INVALID_ENUM, "crStateActiveStencilFaceEXT");
339 return;
340 }
341
342 DIRTY(sb->activeStencilFace, g->neg_bitid);
343 DIRTY(sb->dirty, g->neg_bitid);
344}
345
346#ifdef CRSTATE_DEBUG_STENCIL_ERR
347#define CRSTATE_CLEARERR() do { \
348 while (diff_api.GetError() != GL_NO_ERROR) {} \
349 } while (0)
350
351#define CRSTATE_CHECKGLERR(_op) do {\
352 GLenum _glErr; \
353 CRSTATE_CLEARERR(); \
354 _op; \
355 while ((_glErr = diff_api.GetError()) != GL_NO_ERROR) { Assert(0);} \
356 }while (0)
357#else
358#define CRSTATE_CHECKGLERR(_op) do { _op; } while (0)
359#endif
360
361#define CR_STATE_STENCIL_FUNC_MATCH(_s1, _i1, _s2, _i2) (\
362 (_s1)->buffers[(_i1)].func == (_s2)->buffers[(_i2)].func && \
363 (_s1)->buffers[(_i1)].ref == (_s2)->buffers[(_i2)].ref && \
364 (_s1)->buffers[(_i1)].mask == (_s2)->buffers[(_i2)].mask)
365
366#define CR_STATE_STENCIL_FUNC_COPY(_s1, _i1, _s2, _i2) do { \
367 (_s1)->buffers[(_i1)].func = (_s2)->buffers[(_i2)].func; \
368 (_s1)->buffers[(_i1)].ref = (_s2)->buffers[(_i2)].ref; \
369 (_s1)->buffers[(_i1)].mask = (_s2)->buffers[(_i2)].mask; \
370 } while (0)
371
372
373#define CR_STATE_STENCIL_OP_MATCH(_s1, _i1, _s2, _i2) (\
374 (_s1)->buffers[(_i1)].fail == (_s2)->buffers[(_i2)].fail && \
375 (_s1)->buffers[(_i1)].passDepthFail == (_s2)->buffers[(_i2)].passDepthFail && \
376 (_s1)->buffers[(_i1)].passDepthPass == (_s2)->buffers[(_i2)].passDepthPass)
377
378#define CR_STATE_STENCIL_OP_COPY(_s1, _i1, _s2, _i2) do { \
379 (_s1)->buffers[(_i1)].fail = (_s2)->buffers[(_i2)].fail; \
380 (_s1)->buffers[(_i1)].passDepthFail = (_s2)->buffers[(_i2)].passDepthFail; \
381 (_s1)->buffers[(_i1)].passDepthPass = (_s2)->buffers[(_i2)].passDepthPass; \
382 } while (0)
383
384
385void crStateStencilDiff(CRStencilBits *b, CRbitvalue *bitID,
386 CRContext *fromCtx, CRContext *toCtx)
387{
388 CRStencilState *from = &(fromCtx->stencil);
389 CRStencilState *to = &(toCtx->stencil);
390 unsigned int j, i;
391 GLenum activeFace;
392 GLboolean backIsSet = GL_FALSE, frontIsSet = GL_FALSE, frontBackDirty, frontDirty, backDirty;
393 GLchar frontMatch = -1, backMatch = -1, toFrontBackMatch = -1;
394 CRbitvalue nbitID[CR_MAX_BITARRAY];
395 for (j=0;j<CR_MAX_BITARRAY;j++)
396 nbitID[j] = ~bitID[j];
397 i = 0; /* silence compiler */
398
399 if (CHECKDIRTY(b->enable, bitID))
400 {
401 glAble able[2];
402 able[0] = diff_api.Disable;
403 able[1] = diff_api.Enable;
404 if (from->stencilTest != to->stencilTest)
405 {
406 able[to->stencilTest](GL_STENCIL_TEST);
407 from->stencilTest = to->stencilTest;
408 }
409 CLEARDIRTY(b->enable, nbitID);
410 }
411
412 if (CHECKDIRTY(b->enableTwoSideEXT, bitID))
413 {
414 glAble able[2];
415 able[0] = diff_api.Disable;
416 able[1] = diff_api.Enable;
417 if (from->stencilTwoSideEXT != to->stencilTwoSideEXT)
418 {
419 able[to->stencilTwoSideEXT](GL_STENCIL_TEST_TWO_SIDE_EXT);
420 from->stencilTwoSideEXT = to->stencilTwoSideEXT;
421 }
422 CLEARDIRTY(b->enableTwoSideEXT, nbitID);
423 }
424
425 if (CHECKDIRTY(b->clearValue, bitID))
426 {
427 if (from->clearValue != to->clearValue)
428 {
429 diff_api.ClearStencil (to->clearValue);
430 from->clearValue = to->clearValue;
431 }
432 CLEARDIRTY(b->clearValue, nbitID);
433 }
434
435 activeFace = to->activeStencilFace;
436
437
438 /* func */
439 frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, bitID);
440 frontDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func, bitID);
441 backDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func, bitID);
442#define CR_STATE_STENCIL_FUNC_FRONT_MATCH() ( \
443 frontMatch >= 0 ? \
444 frontMatch \
445 : (frontMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
446
447#define CR_STATE_STENCIL_FUNC_BACK_MATCH() ( \
448 backMatch >= 0 ? \
449 backMatch \
450 : (backMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
451
452#define CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH() ( \
453 toFrontBackMatch >= 0 ? \
454 toFrontBackMatch \
455 : (toFrontBackMatch = CR_STATE_STENCIL_FUNC_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
456
457 if (frontBackDirty)
458 {
459 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH()
460 || !CR_STATE_STENCIL_FUNC_BACK_MATCH())
461 {
462 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
463 {
464 if (activeFace == GL_BACK)
465 {
466 diff_api.ActiveStencilFaceEXT(GL_FRONT);
467 activeFace = GL_FRONT;
468 }
469
470 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
471 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
472 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
473
474 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
475 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
476 frontIsSet = GL_TRUE;
477 backIsSet = GL_TRUE;
478 }
479 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
480 {
481 if (activeFace == GL_BACK)
482 {
483 diff_api.ActiveStencilFaceEXT(GL_FRONT);
484 activeFace = GL_FRONT;
485 }
486
487 diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
488 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
489 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
490
491 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
492 frontIsSet = GL_TRUE;
493 }
494 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
495 {
496 if (activeFace == GL_BACK)
497 {
498 diff_api.ActiveStencilFaceEXT(GL_FRONT);
499 activeFace = GL_FRONT;
500 }
501
502 diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
503 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
504 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask);
505
506 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
507
508 backIsSet = GL_TRUE;
509 }
510 }
511
512 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, nbitID);
513 }
514
515 if (frontDirty)
516 {
517 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
518 {
519 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
520 {
521 if (!frontIsSet || !backIsSet)
522 {
523 if (activeFace == GL_BACK)
524 {
525 diff_api.ActiveStencilFaceEXT(GL_FRONT);
526 activeFace = GL_FRONT;
527 }
528
529 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
530 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
531 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
532
533 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
534 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
535
536 frontIsSet = GL_TRUE;
537 backIsSet = GL_TRUE;
538 }
539 }
540 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
541 {
542 if (!frontIsSet)
543 {
544 if (activeFace == GL_BACK)
545 {
546 diff_api.ActiveStencilFaceEXT(GL_FRONT);
547 activeFace = GL_FRONT;
548 }
549
550 diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
551 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
552 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
553
554 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
555 frontIsSet = GL_TRUE;
556 }
557 }
558 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
559 {
560 if (!backIsSet)
561 {
562 if (activeFace == GL_BACK)
563 {
564 diff_api.ActiveStencilFaceEXT(GL_FRONT);
565 activeFace = GL_FRONT;
566 }
567
568 diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
569 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
570 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask);
571 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
572 backIsSet = GL_TRUE;
573 }
574 }
575 }
576 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func, nbitID);
577 }
578
579
580 if (backDirty)
581 {
582 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
583 {
584 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
585 {
586 if (!frontIsSet || !backIsSet)
587 {
588 if (activeFace == GL_BACK)
589 {
590 diff_api.ActiveStencilFaceEXT(GL_FRONT);
591 activeFace = GL_FRONT;
592 }
593
594 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
595 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
596 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
597
598 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
599 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
600
601 frontIsSet = GL_TRUE;
602 backIsSet = GL_TRUE;
603 }
604 }
605 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
606 {
607 if (!frontIsSet)
608 {
609 if (activeFace == GL_BACK)
610 {
611 diff_api.ActiveStencilFaceEXT(GL_FRONT);
612 activeFace = GL_FRONT;
613 }
614
615 diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
616 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
617 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
618
619 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
620 frontIsSet = GL_TRUE;
621 }
622 }
623 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
624 {
625 if (!backIsSet)
626 {
627 if (activeFace == GL_BACK)
628 {
629 diff_api.ActiveStencilFaceEXT(GL_FRONT);
630 activeFace = GL_FRONT;
631 }
632
633 diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
634 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
635 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask);
636 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
637 backIsSet = GL_TRUE;
638 }
639 }
640 }
641 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func, nbitID);
642 }
643
644 if (CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func, bitID))
645 {
646 if (!CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK))
647 {
648 if (activeFace == GL_FRONT)
649 {
650 diff_api.ActiveStencilFaceEXT(GL_BACK);
651 activeFace = GL_BACK;
652 }
653
654 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].func,
655 to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].ref,
656 to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].mask);
657 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK);
658 }
659 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func, nbitID);
660 }
661
662#undef CR_STATE_STENCIL_FUNC_FRONT_MATCH
663#undef CR_STATE_STENCIL_FUNC_BACK_MATCH
664#undef CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH
665
666 /* op */
667 backIsSet = GL_FALSE, frontIsSet = GL_FALSE;
668 frontMatch = -1, backMatch = -1, toFrontBackMatch = -1;
669 frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op, bitID);
670 frontDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op, bitID);
671 backDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op, bitID);
672
673#define CR_STATE_STENCIL_OP_FRONT_MATCH() ( \
674 frontMatch >= 0 ? \
675 frontMatch \
676 : (frontMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
677
678#define CR_STATE_STENCIL_OP_BACK_MATCH() ( \
679 backMatch >= 0 ? \
680 backMatch \
681 : (backMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
682
683#define CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH() ( \
684 toFrontBackMatch >= 0 ? \
685 toFrontBackMatch \
686 : (toFrontBackMatch = CR_STATE_STENCIL_OP_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
687
688 if (frontBackDirty)
689 {
690 if (!CR_STATE_STENCIL_OP_FRONT_MATCH()
691 || !CR_STATE_STENCIL_OP_BACK_MATCH())
692 {
693 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
694 {
695 if (activeFace == GL_BACK)
696 {
697 diff_api.ActiveStencilFaceEXT(GL_FRONT);
698 activeFace = GL_FRONT;
699 }
700
701 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
702 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
703 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
704
705 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
706 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
707
708 frontIsSet = GL_TRUE;
709 backIsSet = GL_TRUE;
710 }
711 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
712 {
713 if (activeFace == GL_BACK)
714 {
715 diff_api.ActiveStencilFaceEXT(GL_FRONT);
716 activeFace = GL_FRONT;
717 }
718
719 diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
720 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
721 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
722 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
723 frontIsSet = GL_TRUE;
724 }
725 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
726 {
727 if (activeFace == GL_BACK)
728 {
729 diff_api.ActiveStencilFaceEXT(GL_FRONT);
730 activeFace = GL_FRONT;
731 }
732
733 diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
734 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
735 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass);
736 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
737 backIsSet = GL_TRUE;
738 }
739 }
740
741 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op, nbitID);
742 }
743
744 if (frontDirty)
745 {
746 if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
747 {
748 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
749 {
750 if (!frontIsSet || !backIsSet)
751 {
752 if (activeFace == GL_BACK)
753 {
754 diff_api.ActiveStencilFaceEXT(GL_FRONT);
755 activeFace = GL_FRONT;
756 }
757
758 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
759 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
760 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
761
762 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
763 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
764
765 frontIsSet = GL_TRUE;
766 backIsSet = GL_TRUE;
767 }
768 }
769 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
770 {
771 if (!frontIsSet)
772 {
773 if (activeFace == GL_BACK)
774 {
775 diff_api.ActiveStencilFaceEXT(GL_FRONT);
776 activeFace = GL_FRONT;
777 }
778
779 diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
780 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
781 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
782
783 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
784
785 frontIsSet = GL_TRUE;
786 }
787 }
788 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
789 {
790 if (!backIsSet)
791 {
792 if (activeFace == GL_BACK)
793 {
794 diff_api.ActiveStencilFaceEXT(GL_FRONT);
795 activeFace = GL_FRONT;
796 }
797
798 diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
799 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
800 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass);
801 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
802 backIsSet = GL_TRUE;
803 }
804 }
805 }
806 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op, nbitID);
807 }
808
809
810 if (backDirty)
811 {
812 if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
813 {
814 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
815 {
816 if (!frontIsSet || !backIsSet)
817 {
818 if (activeFace == GL_BACK)
819 {
820 diff_api.ActiveStencilFaceEXT(GL_FRONT);
821 activeFace = GL_FRONT;
822 }
823
824 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
825 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
826 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
827
828 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
829 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
830
831 frontIsSet = GL_TRUE;
832 backIsSet = GL_TRUE;
833 }
834 }
835 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
836 {
837 if (!frontIsSet)
838 {
839 if (activeFace == GL_BACK)
840 {
841 diff_api.ActiveStencilFaceEXT(GL_FRONT);
842 activeFace = GL_FRONT;
843 }
844
845 diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
846 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
847 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
848
849 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
850
851 frontIsSet = GL_TRUE;
852 }
853 }
854 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
855 {
856 if (!backIsSet)
857 {
858 if (activeFace == GL_BACK)
859 {
860 diff_api.ActiveStencilFaceEXT(GL_FRONT);
861 activeFace = GL_FRONT;
862 }
863
864 diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
865 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
866 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass);
867 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
868 backIsSet = GL_TRUE;
869 }
870 }
871 }
872 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op, nbitID);
873 }
874
875 if (CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op, bitID))
876 {
877 if (!CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK))
878 {
879 if (activeFace == GL_FRONT)
880 {
881 diff_api.ActiveStencilFaceEXT(GL_BACK);
882 activeFace = GL_BACK;
883 }
884
885 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].fail,
886 to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].passDepthFail,
887 to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].passDepthPass);
888 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK);
889 }
890 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op, nbitID);
891 }
892
893#undef CR_STATE_STENCIL_OP_FRONT_MATCH
894#undef CR_STATE_STENCIL_OP_BACK_MATCH
895#undef CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH
896
897
898 if (activeFace != to->activeStencilFace)
899 {
900 diff_api.ActiveStencilFaceEXT(activeFace);
901 }
902
903 if (CHECKDIRTY(b->activeStencilFace, bitID))
904 {
905 if (from->activeStencilFace != to->activeStencilFace)
906 {
907 /* we already did it ( see above )*/
908 /* diff_api.ActiveStencilFaceEXT(to->activeStencilFace); */
909 from->activeStencilFace = to->activeStencilFace;
910 }
911 CLEARDIRTY(b->activeStencilFace, nbitID);
912 }
913
914 if (CHECKDIRTY(b->writeMask, bitID))
915 {
916 if (from->writeMask != to->writeMask)
917 {
918 diff_api.StencilMask (to->writeMask);
919 from->writeMask = to->writeMask;
920 }
921 CLEARDIRTY(b->writeMask, nbitID);
922 }
923 CLEARDIRTY(b->dirty, nbitID);
924}
925
926void crStateStencilSwitch(CRStencilBits *b, CRbitvalue *bitID,
927 CRContext *fromCtx, CRContext *toCtx)
928{
929 CRStencilState *from = &(fromCtx->stencil);
930 CRStencilState *to = &(toCtx->stencil);
931 unsigned int j, i;
932 GLenum activeFace;
933 GLboolean backIsSet = GL_FALSE, frontIsSet = GL_FALSE, frontBackDirty, frontDirty, backDirty;
934 GLchar frontMatch = -1, backMatch = -1, toFrontBackMatch = -1;
935 CRbitvalue nbitID[CR_MAX_BITARRAY];
936 for (j=0;j<CR_MAX_BITARRAY;j++)
937 nbitID[j] = ~bitID[j];
938 i = 0; /* silence compiler */
939
940 if (CHECKDIRTY(b->enable, bitID))
941 {
942 glAble able[2];
943 able[0] = diff_api.Disable;
944 able[1] = diff_api.Enable;
945 if (from->stencilTest != to->stencilTest)
946 {
947 CRSTATE_CHECKGLERR(able[to->stencilTest](GL_STENCIL_TEST));
948 FILLDIRTY(b->enable);
949 FILLDIRTY(b->dirty);
950 }
951 CLEARDIRTY(b->enable, nbitID);
952 }
953 if (CHECKDIRTY(b->enableTwoSideEXT, bitID))
954 {
955 glAble able[2];
956 able[0] = diff_api.Disable;
957 able[1] = diff_api.Enable;
958 if (from->stencilTwoSideEXT != to->stencilTwoSideEXT)
959 {
960 CRSTATE_CHECKGLERR(able[to->stencilTwoSideEXT](GL_STENCIL_TEST_TWO_SIDE_EXT));
961 FILLDIRTY(b->enableTwoSideEXT);
962 FILLDIRTY(b->dirty);
963 }
964 CLEARDIRTY(b->enableTwoSideEXT, nbitID);
965 }
966 if (CHECKDIRTY(b->clearValue, bitID))
967 {
968 if (from->clearValue != to->clearValue)
969 {
970 CRSTATE_CHECKGLERR(diff_api.ClearStencil (to->clearValue));
971 FILLDIRTY(b->clearValue);
972 FILLDIRTY(b->dirty);
973 }
974 CLEARDIRTY(b->clearValue, nbitID);
975 }
976
977 activeFace = from->activeStencilFace;
978
979 /* func */
980 frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, bitID);
981 frontDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func, bitID);
982 backDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func, bitID);
983#define CR_STATE_STENCIL_FUNC_FRONT_MATCH() ( \
984 frontMatch >= 0 ? \
985 frontMatch \
986 : (frontMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
987
988#define CR_STATE_STENCIL_FUNC_BACK_MATCH() ( \
989 backMatch >= 0 ? \
990 backMatch \
991 : (backMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
992
993#define CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH() ( \
994 toFrontBackMatch >= 0 ? \
995 toFrontBackMatch \
996 : (toFrontBackMatch = CR_STATE_STENCIL_FUNC_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
997
998 if (frontBackDirty)
999 {
1000 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH()
1001 || !CR_STATE_STENCIL_FUNC_BACK_MATCH())
1002 {
1003 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
1004 {
1005 if (activeFace == GL_BACK)
1006 {
1007 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1008 activeFace = GL_FRONT;
1009 }
1010
1011 CRSTATE_CHECKGLERR(diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1012 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1013 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask));
1014
1015 frontIsSet = GL_TRUE;
1016 backIsSet = GL_TRUE;
1017 }
1018 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
1019 {
1020 if (activeFace == GL_BACK)
1021 {
1022 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1023 activeFace = GL_FRONT;
1024 }
1025
1026 CRSTATE_CHECKGLERR(diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1027 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1028 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask));
1029 frontIsSet = GL_TRUE;
1030 }
1031 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
1032 {
1033 if (activeFace == GL_BACK)
1034 {
1035 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1036 activeFace = GL_FRONT;
1037 }
1038
1039 CRSTATE_CHECKGLERR(diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
1040 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
1041 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask));
1042 backIsSet = GL_TRUE;
1043 }
1044 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func);
1045 FILLDIRTY(b->dirty);
1046 }
1047
1048 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, nbitID);
1049 }
1050
1051 if (frontDirty)
1052 {
1053 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
1054 {
1055 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
1056 {
1057 if (!frontIsSet || !backIsSet)
1058 {
1059 if (activeFace == GL_BACK)
1060 {
1061 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1062 activeFace = GL_FRONT;
1063 }
1064
1065 CRSTATE_CHECKGLERR(diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1066 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1067 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask));
1068
1069 frontIsSet = GL_TRUE;
1070 backIsSet = GL_TRUE;
1071 }
1072 }
1073 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
1074 {
1075 if (!frontIsSet)
1076 {
1077 if (activeFace == GL_BACK)
1078 {
1079 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1080 activeFace = GL_FRONT;
1081 }
1082
1083 CRSTATE_CHECKGLERR(diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1084 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1085 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask));
1086 frontIsSet = GL_TRUE;
1087 }
1088 }
1089 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
1090 {
1091 if (!backIsSet)
1092 {
1093 if (activeFace == GL_BACK)
1094 {
1095 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1096 activeFace = GL_FRONT;
1097 }
1098
1099 CRSTATE_CHECKGLERR(diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
1100 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
1101 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask));
1102 backIsSet = GL_TRUE;
1103 }
1104 }
1105 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func);
1106 FILLDIRTY(b->dirty);
1107 }
1108 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func, nbitID);
1109 }
1110
1111
1112 if (backDirty)
1113 {
1114 if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
1115 {
1116 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
1117 {
1118 if (!frontIsSet || !backIsSet)
1119 {
1120 if (activeFace == GL_BACK)
1121 {
1122 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1123 activeFace = GL_FRONT;
1124 }
1125
1126 CRSTATE_CHECKGLERR(diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1127 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1128 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask));
1129
1130 frontIsSet = GL_TRUE;
1131 backIsSet = GL_TRUE;
1132 }
1133 }
1134 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
1135 {
1136 if (!frontIsSet)
1137 {
1138 if (activeFace == GL_BACK)
1139 {
1140 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1141 activeFace = GL_FRONT;
1142 }
1143
1144 CRSTATE_CHECKGLERR(diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1145 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1146 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask));
1147 frontIsSet = GL_TRUE;
1148 }
1149 }
1150 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
1151 {
1152 if (!backIsSet)
1153 {
1154 if (activeFace == GL_BACK)
1155 {
1156 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1157 activeFace = GL_FRONT;
1158 }
1159
1160 CRSTATE_CHECKGLERR(diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
1161 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
1162 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask));
1163 backIsSet = GL_TRUE;
1164 }
1165 }
1166 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func);
1167 FILLDIRTY(b->dirty);
1168 }
1169 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func, nbitID);
1170 }
1171
1172 if (CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func, bitID))
1173 {
1174 if (!CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK))
1175 {
1176 if (activeFace == GL_FRONT)
1177 {
1178 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_BACK));
1179 activeFace = GL_BACK;
1180 }
1181
1182 CRSTATE_CHECKGLERR(diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].func,
1183 to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].ref,
1184 to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].mask));
1185
1186 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func);
1187 FILLDIRTY(b->dirty);
1188 }
1189 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func, nbitID);
1190 }
1191
1192#undef CR_STATE_STENCIL_FUNC_FRONT_MATCH
1193#undef CR_STATE_STENCIL_FUNC_BACK_MATCH
1194#undef CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH
1195
1196 /* op */
1197 backIsSet = GL_FALSE, frontIsSet = GL_FALSE;
1198 frontMatch = -1, backMatch = -1, toFrontBackMatch = -1;
1199 frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op, bitID);
1200 frontDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op, bitID);
1201 backDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op, bitID);
1202
1203#define CR_STATE_STENCIL_OP_FRONT_MATCH() ( \
1204 frontMatch >= 0 ? \
1205 frontMatch \
1206 : (frontMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
1207
1208#define CR_STATE_STENCIL_OP_BACK_MATCH() ( \
1209 backMatch >= 0 ? \
1210 backMatch \
1211 : (backMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
1212
1213#define CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH() ( \
1214 toFrontBackMatch >= 0 ? \
1215 toFrontBackMatch \
1216 : (toFrontBackMatch = CR_STATE_STENCIL_OP_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
1217
1218 if (frontBackDirty)
1219 {
1220 if (!CR_STATE_STENCIL_OP_FRONT_MATCH()
1221 || !CR_STATE_STENCIL_OP_BACK_MATCH())
1222 {
1223 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
1224 {
1225 if (activeFace == GL_BACK)
1226 {
1227 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_FRONT));
1228 activeFace = GL_FRONT;
1229 }
1230
1231 CRSTATE_CHECKGLERR(diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1232 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1233 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass));
1234
1235 frontIsSet = GL_TRUE;
1236 backIsSet = GL_TRUE;
1237 }
1238 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
1239 {
1240 if (activeFace == GL_BACK)
1241 {
1242 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_FRONT));
1243 activeFace = GL_FRONT;
1244 }
1245
1246 CRSTATE_CHECKGLERR(diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1247 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1248 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass));
1249 frontIsSet = GL_TRUE;
1250 }
1251 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
1252 {
1253 if (activeFace == GL_BACK)
1254 {
1255 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_FRONT));
1256 activeFace = GL_FRONT;
1257 }
1258
1259 CRSTATE_CHECKGLERR(diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
1260 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
1261 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass));
1262 backIsSet = GL_TRUE;
1263 }
1264 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op);
1265 FILLDIRTY(b->dirty);
1266 }
1267
1268 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op, nbitID);
1269 }
1270
1271 if (frontDirty)
1272 {
1273 if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
1274 {
1275 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
1276 {
1277 if (!frontIsSet || !backIsSet)
1278 {
1279 if (activeFace == GL_BACK)
1280 {
1281 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_FRONT));
1282 activeFace = GL_FRONT;
1283 }
1284
1285 CRSTATE_CHECKGLERR(diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1286 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1287 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass));
1288
1289 frontIsSet = GL_TRUE;
1290 backIsSet = GL_TRUE;
1291 }
1292 }
1293 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
1294 {
1295 if (!frontIsSet)
1296 {
1297 if (activeFace == GL_BACK)
1298 {
1299 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_FRONT));
1300 activeFace = GL_FRONT;
1301 }
1302
1303 CRSTATE_CHECKGLERR(diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1304 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1305 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass));
1306 frontIsSet = GL_TRUE;
1307 }
1308 }
1309 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
1310 {
1311 if (!backIsSet)
1312 {
1313 if (activeFace == GL_BACK)
1314 {
1315 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_FRONT));
1316 activeFace = GL_FRONT;
1317 }
1318
1319 CRSTATE_CHECKGLERR(diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
1320 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
1321 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass));
1322 backIsSet = GL_TRUE;
1323 }
1324 }
1325
1326 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op);
1327 FILLDIRTY(b->dirty);
1328 }
1329 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op, nbitID);
1330 }
1331
1332
1333 if (backDirty)
1334 {
1335 if (!CR_STATE_STENCIL_OP_BACK_MATCH())
1336 {
1337 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
1338 {
1339 if (!frontIsSet || !backIsSet)
1340 {
1341 if (activeFace == GL_BACK)
1342 {
1343 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_FRONT));
1344 activeFace = GL_FRONT;
1345 }
1346
1347 CRSTATE_CHECKGLERR(diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1348 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1349 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass));
1350
1351 frontIsSet = GL_TRUE;
1352 backIsSet = GL_TRUE;
1353 }
1354 }
1355 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
1356 {
1357 if (!frontIsSet)
1358 {
1359 if (activeFace == GL_BACK)
1360 {
1361 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_FRONT));
1362 activeFace = GL_FRONT;
1363 }
1364
1365 CRSTATE_CHECKGLERR(diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1366 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1367 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass));
1368 frontIsSet = GL_TRUE;
1369 }
1370 }
1371 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
1372 {
1373 if (!backIsSet)
1374 {
1375 if (activeFace == GL_BACK)
1376 {
1377 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_FRONT));
1378 activeFace = GL_FRONT;
1379 }
1380
1381 CRSTATE_CHECKGLERR(diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
1382 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
1383 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass));
1384 backIsSet = GL_TRUE;
1385 }
1386 }
1387
1388 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op);
1389 FILLDIRTY(b->dirty);
1390 }
1391 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op, nbitID);
1392 }
1393
1394 if (CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op, bitID))
1395 {
1396 if (!CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK))
1397 {
1398 if (activeFace == GL_FRONT)
1399 {
1400 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(GL_BACK));
1401 activeFace = GL_BACK;
1402 }
1403
1404 CRSTATE_CHECKGLERR(diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].fail,
1405 to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].passDepthFail,
1406 to->buffers[CRSTATE_STENCIL_BUFFER_ID_TWO_SIDE_BACK].passDepthPass));
1407
1408 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op);
1409 FILLDIRTY(b->dirty);
1410 }
1411 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op, nbitID);
1412 }
1413
1414#undef CR_STATE_STENCIL_OP_FRONT_MATCH
1415#undef CR_STATE_STENCIL_OP_BACK_MATCH
1416#undef CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH
1417
1418 if (activeFace != to->activeStencilFace)
1419 {
1420 CRSTATE_CHECKGLERR(diff_api.ActiveStencilFaceEXT(activeFace));
1421 }
1422
1423 if (CHECKDIRTY(b->activeStencilFace, bitID))
1424 {
1425 if (from->activeStencilFace != to->activeStencilFace)
1426 {
1427 /* we already did it ( see above )*/
1428 /* diff_api.ActiveStencilFaceEXT(to->activeStencilFace); */
1429 FILLDIRTY(b->activeStencilFace);
1430 FILLDIRTY(b->dirty);
1431 }
1432 CLEARDIRTY(b->activeStencilFace, nbitID);
1433 }
1434
1435 if (CHECKDIRTY(b->writeMask, bitID))
1436 {
1437 if (from->writeMask != to->writeMask)
1438 {
1439 CRSTATE_CHECKGLERR(diff_api.StencilMask (to->writeMask));
1440 FILLDIRTY(b->writeMask);
1441 FILLDIRTY(b->dirty);
1442 }
1443 CLEARDIRTY(b->writeMask, nbitID);
1444 }
1445
1446 CLEARDIRTY(b->dirty, nbitID);
1447}
1448
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