VirtualBox

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

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

GuestHost/OpenGL: scm updates

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