VirtualBox

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

Last change on this file since 55043 was 44332, checked in by vboxsync, 12 years ago

crOpenGL: additional stencil state fixes

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