VirtualBox

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

最後變更 在這個檔案從44326是 44326,由 vboxsync 提交於 12 年 前

crOpenGL: 1. stencil state fixes, 2. missing gets

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 51.4 KB
 
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#define CR_STATE_STENCIL_FUNC_MATCH(_s1, _i1, _s2, _i2) (\
345 (_s1)->buffers[(_i1)].func == (_s2)->buffers[(_i2)].func && \
346 (_s1)->buffers[(_i1)].ref == (_s2)->buffers[(_i2)].ref && \
347 (_s1)->buffers[(_i1)].mask == (_s2)->buffers[(_i2)].mask)
348
349#define CR_STATE_STENCIL_FUNC_COPY(_s1, _i1, _s2, _i2) do { \
350 (_s1)->buffers[(_i1)].func = (_s2)->buffers[(_i2)].func; \
351 (_s1)->buffers[(_i1)].ref = (_s2)->buffers[(_i2)].ref; \
352 (_s1)->buffers[(_i1)].mask = (_s2)->buffers[(_i2)].mask; \
353 } while (0)
354
355
356#define CR_STATE_STENCIL_OP_MATCH(_s1, _i1, _s2, _i2) (\
357 (_s1)->buffers[(_i1)].fail == (_s2)->buffers[(_i2)].fail && \
358 (_s1)->buffers[(_i1)].passDepthFail == (_s2)->buffers[(_i2)].passDepthFail && \
359 (_s1)->buffers[(_i1)].passDepthPass == (_s2)->buffers[(_i2)].passDepthPass)
360
361#define CR_STATE_STENCIL_OP_COPY(_s1, _i1, _s2, _i2) do { \
362 (_s1)->buffers[(_i1)].fail = (_s2)->buffers[(_i2)].fail; \
363 (_s1)->buffers[(_i1)].passDepthFail = (_s2)->buffers[(_i2)].passDepthFail; \
364 (_s1)->buffers[(_i1)].passDepthPass = (_s2)->buffers[(_i2)].passDepthPass; \
365 } while (0)
366
367
368void crStateStencilDiff(CRStencilBits *b, CRbitvalue *bitID,
369 CRContext *fromCtx, CRContext *toCtx)
370{
371 CRStencilState *from = &(fromCtx->stencil);
372 CRStencilState *to = &(toCtx->stencil);
373 unsigned int j, i;
374 GLenum activeFace;
375 GLboolean backIsSet = GL_FALSE, frontIsSet = GL_FALSE, frontBackDirty, frontDirty, backDirty;
376 GLchar frontMatch = -1, backMatch = -1, toFrontBackMatch = -1;
377 CRbitvalue nbitID[CR_MAX_BITARRAY];
378 for (j=0;j<CR_MAX_BITARRAY;j++)
379 nbitID[j] = ~bitID[j];
380 i = 0; /* silence compiler */
381
382 if (CHECKDIRTY(b->enable, bitID))
383 {
384 glAble able[2];
385 able[0] = diff_api.Disable;
386 able[1] = diff_api.Enable;
387 if (from->stencilTest != to->stencilTest)
388 {
389 able[to->stencilTest](GL_STENCIL_TEST);
390 from->stencilTest = to->stencilTest;
391 }
392 CLEARDIRTY(b->enable, nbitID);
393 }
394
395 if (CHECKDIRTY(b->enableTwoSideEXT, bitID))
396 {
397 glAble able[2];
398 able[0] = diff_api.Disable;
399 able[1] = diff_api.Enable;
400 if (from->stencilTwoSideEXT != to->stencilTwoSideEXT)
401 {
402 able[to->stencilTwoSideEXT](GL_STENCIL_TEST_TWO_SIDE_EXT);
403 from->stencilTwoSideEXT = to->stencilTwoSideEXT;
404 }
405 CLEARDIRTY(b->enableTwoSideEXT, nbitID);
406 }
407
408 if (CHECKDIRTY(b->clearValue, bitID))
409 {
410 if (from->clearValue != to->clearValue)
411 {
412 diff_api.ClearStencil (to->clearValue);
413 from->clearValue = to->clearValue;
414 }
415 CLEARDIRTY(b->clearValue, nbitID);
416 }
417
418 activeFace = to->activeStencilFace;
419
420
421 /* func */
422 frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, bitID);
423 frontDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func, bitID);
424 backDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func, bitID);
425#define CR_STATE_STENCIL_FUNC_FRONT_MATCH() ( \
426 frontMatch >= 0 ? \
427 frontMatch \
428 : (frontMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
429
430#define CR_STATE_STENCIL_FUNC_BACK_MATCH() ( \
431 backMatch >= 0 ? \
432 backMatch \
433 : (backMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
434
435#define CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH() ( \
436 toFrontBackMatch >= 0 ? \
437 toFrontBackMatch \
438 : (toFrontBackMatch = CR_STATE_STENCIL_FUNC_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
439
440 if (frontBackDirty)
441 {
442 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH()
443 || !CR_STATE_STENCIL_FUNC_BACK_MATCH())
444 {
445 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
446 {
447 if (activeFace == GL_BACK)
448 {
449 diff_api.ActiveStencilFaceEXT(GL_FRONT);
450 activeFace = GL_FRONT;
451 }
452
453 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
454 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
455 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
456
457 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
458 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
459 frontIsSet = GL_TRUE;
460 backIsSet = GL_TRUE;
461 }
462 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
463 {
464 if (activeFace == GL_BACK)
465 {
466 diff_api.ActiveStencilFaceEXT(GL_FRONT);
467 activeFace = GL_FRONT;
468 }
469
470 diff_api.StencilFuncSeparate (GL_FRONT, 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 frontIsSet = GL_TRUE;
476 }
477 else if (!CR_STATE_STENCIL_FUNC_BACK_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_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
486 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
487 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask);
488
489 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
490
491 backIsSet = GL_TRUE;
492 }
493 }
494
495 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, nbitID);
496 }
497
498 if (frontDirty)
499 {
500 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
501 {
502 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
503 {
504 if (!frontIsSet || !backIsSet)
505 {
506 if (activeFace == GL_BACK)
507 {
508 diff_api.ActiveStencilFaceEXT(GL_FRONT);
509 activeFace = GL_FRONT;
510 }
511
512 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
513 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
514 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
515
516 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
517 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
518
519 frontIsSet = GL_TRUE;
520 backIsSet = GL_TRUE;
521 }
522 }
523 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
524 {
525 if (!frontIsSet)
526 {
527 if (activeFace == GL_BACK)
528 {
529 diff_api.ActiveStencilFaceEXT(GL_FRONT);
530 activeFace = GL_FRONT;
531 }
532
533 diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
534 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
535 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
536
537 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
538 frontIsSet = GL_TRUE;
539 }
540 }
541 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
542 {
543 if (!backIsSet)
544 {
545 if (activeFace == GL_BACK)
546 {
547 diff_api.ActiveStencilFaceEXT(GL_FRONT);
548 activeFace = GL_FRONT;
549 }
550
551 diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
552 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
553 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask);
554 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
555 backIsSet = GL_TRUE;
556 }
557 }
558 }
559 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func, nbitID);
560 }
561
562
563 if (backDirty)
564 {
565 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
566 {
567 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
568 {
569 if (!frontIsSet || !backIsSet)
570 {
571 if (activeFace == GL_BACK)
572 {
573 diff_api.ActiveStencilFaceEXT(GL_FRONT);
574 activeFace = GL_FRONT;
575 }
576
577 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
578 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
579 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
580
581 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
582 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
583
584 frontIsSet = GL_TRUE;
585 backIsSet = GL_TRUE;
586 }
587 }
588 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
589 {
590 if (!frontIsSet)
591 {
592 if (activeFace == GL_BACK)
593 {
594 diff_api.ActiveStencilFaceEXT(GL_FRONT);
595 activeFace = GL_FRONT;
596 }
597
598 diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
599 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
600 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
601
602 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
603 frontIsSet = GL_TRUE;
604 }
605 }
606 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
607 {
608 if (!backIsSet)
609 {
610 if (activeFace == GL_BACK)
611 {
612 diff_api.ActiveStencilFaceEXT(GL_FRONT);
613 activeFace = GL_FRONT;
614 }
615
616 diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
617 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
618 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask);
619 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
620 backIsSet = GL_TRUE;
621 }
622 }
623 }
624 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func, nbitID);
625 }
626
627 if (CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func, bitID))
628 {
629 if (CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK))
630 {
631 if (activeFace == GL_FRONT)
632 {
633 diff_api.ActiveStencilFaceEXT(GL_BACK);
634 activeFace = GL_BACK;
635 }
636
637 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func,
638 to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].ref,
639 to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].mask);
640 CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK);
641 }
642 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func, nbitID);
643 }
644
645#undef CR_STATE_STENCIL_FUNC_FRONT_MATCH
646#undef CR_STATE_STENCIL_FUNC_BACK_MATCH
647#undef CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH
648
649 /* op */
650 backIsSet = GL_FALSE, frontIsSet = GL_FALSE;
651 frontMatch = -1, backMatch = -1, toFrontBackMatch = -1;
652 frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op, bitID);
653 frontDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op, bitID);
654 backDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op, bitID);
655
656#define CR_STATE_STENCIL_OP_FRONT_MATCH() ( \
657 frontMatch >= 0 ? \
658 frontMatch \
659 : (frontMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
660
661#define CR_STATE_STENCIL_OP_BACK_MATCH() ( \
662 backMatch >= 0 ? \
663 backMatch \
664 : (backMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
665
666#define CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH() ( \
667 toFrontBackMatch >= 0 ? \
668 toFrontBackMatch \
669 : (toFrontBackMatch = CR_STATE_STENCIL_OP_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
670
671 if (frontBackDirty)
672 {
673 if (!CR_STATE_STENCIL_OP_FRONT_MATCH()
674 || !CR_STATE_STENCIL_OP_BACK_MATCH())
675 {
676 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
677 {
678 if (activeFace == GL_BACK)
679 {
680 diff_api.ActiveStencilFaceEXT(GL_FRONT);
681 activeFace = GL_FRONT;
682 }
683
684 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
685 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
686 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
687
688 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
689 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
690
691 frontIsSet = GL_TRUE;
692 backIsSet = GL_TRUE;
693 }
694 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
695 {
696 if (activeFace == GL_BACK)
697 {
698 diff_api.ActiveStencilFaceEXT(GL_FRONT);
699 activeFace = GL_FRONT;
700 }
701
702 diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
703 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
704 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
705 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
706 frontIsSet = GL_TRUE;
707 }
708 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
709 {
710 if (activeFace == GL_BACK)
711 {
712 diff_api.ActiveStencilFaceEXT(GL_FRONT);
713 activeFace = GL_FRONT;
714 }
715
716 diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
717 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
718 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass);
719 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
720 backIsSet = GL_TRUE;
721 }
722 }
723
724 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op, nbitID);
725 }
726
727 if (frontDirty)
728 {
729 if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
730 {
731 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
732 {
733 if (!frontIsSet || !backIsSet)
734 {
735 if (activeFace == GL_BACK)
736 {
737 diff_api.ActiveStencilFaceEXT(GL_FRONT);
738 activeFace = GL_FRONT;
739 }
740
741 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
742 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
743 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
744
745 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
746 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
747
748 frontIsSet = GL_TRUE;
749 backIsSet = GL_TRUE;
750 }
751 }
752 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
753 {
754 if (!frontIsSet)
755 {
756 if (activeFace == GL_BACK)
757 {
758 diff_api.ActiveStencilFaceEXT(GL_FRONT);
759 activeFace = GL_FRONT;
760 }
761
762 diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
763 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
764 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
765
766 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
767
768 frontIsSet = GL_TRUE;
769 }
770 }
771 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
772 {
773 if (!backIsSet)
774 {
775 if (activeFace == GL_BACK)
776 {
777 diff_api.ActiveStencilFaceEXT(GL_FRONT);
778 activeFace = GL_FRONT;
779 }
780
781 diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
782 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
783 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass);
784 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
785 backIsSet = GL_TRUE;
786 }
787 }
788 }
789 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op, nbitID);
790 }
791
792
793 if (backDirty)
794 {
795 if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
796 {
797 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
798 {
799 if (!frontIsSet || !backIsSet)
800 {
801 if (activeFace == GL_BACK)
802 {
803 diff_api.ActiveStencilFaceEXT(GL_FRONT);
804 activeFace = GL_FRONT;
805 }
806
807 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
808 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
809 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
810
811 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
812 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
813
814 frontIsSet = GL_TRUE;
815 backIsSet = GL_TRUE;
816 }
817 }
818 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
819 {
820 if (!frontIsSet)
821 {
822 if (activeFace == GL_BACK)
823 {
824 diff_api.ActiveStencilFaceEXT(GL_FRONT);
825 activeFace = GL_FRONT;
826 }
827
828 diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
829 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
830 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
831
832 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
833
834 frontIsSet = GL_TRUE;
835 }
836 }
837 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
838 {
839 if (!backIsSet)
840 {
841 if (activeFace == GL_BACK)
842 {
843 diff_api.ActiveStencilFaceEXT(GL_FRONT);
844 activeFace = GL_FRONT;
845 }
846
847 diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
848 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
849 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass);
850 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
851 backIsSet = GL_TRUE;
852 }
853 }
854 }
855 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op, nbitID);
856 }
857
858 if (CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op, bitID))
859 {
860 if (CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK))
861 {
862 if (activeFace == GL_FRONT)
863 {
864 diff_api.ActiveStencilFaceEXT(GL_BACK);
865 activeFace = GL_BACK;
866 }
867
868 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].fail,
869 to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].passDepthFail,
870 to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].passDepthPass);
871 CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK);
872 }
873 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op, nbitID);
874 }
875
876#undef CR_STATE_STENCIL_OP_FRONT_MATCH
877#undef CR_STATE_STENCIL_OP_BACK_MATCH
878#undef CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH
879
880
881 if (activeFace != to->activeStencilFace)
882 {
883 diff_api.ActiveStencilFaceEXT(activeFace);
884 }
885
886 if (CHECKDIRTY(b->activeStencilFace, bitID))
887 {
888 if (from->activeStencilFace != to->activeStencilFace)
889 {
890 /* we already did it ( see above )*/
891 /* diff_api.ActiveStencilFaceEXT(to->activeStencilFace); */
892 from->activeStencilFace = to->activeStencilFace;
893 }
894 CLEARDIRTY(b->activeStencilFace, nbitID);
895 }
896
897 if (CHECKDIRTY(b->writeMask, bitID))
898 {
899 if (from->writeMask != to->writeMask)
900 {
901 diff_api.StencilMask (to->writeMask);
902 from->writeMask = to->writeMask;
903 }
904 CLEARDIRTY(b->writeMask, nbitID);
905 }
906 CLEARDIRTY(b->dirty, nbitID);
907}
908
909void crStateStencilSwitch(CRStencilBits *b, CRbitvalue *bitID,
910 CRContext *fromCtx, CRContext *toCtx)
911{
912 CRStencilState *from = &(fromCtx->stencil);
913 CRStencilState *to = &(toCtx->stencil);
914 unsigned int j, i;
915 GLenum activeFace;
916 GLboolean backIsSet = GL_FALSE, frontIsSet = GL_FALSE, frontBackDirty, frontDirty, backDirty;
917 GLchar frontMatch = -1, backMatch = -1, toFrontBackMatch = -1;
918 CRbitvalue nbitID[CR_MAX_BITARRAY];
919 for (j=0;j<CR_MAX_BITARRAY;j++)
920 nbitID[j] = ~bitID[j];
921 i = 0; /* silence compiler */
922
923 if (CHECKDIRTY(b->enable, bitID))
924 {
925 glAble able[2];
926 able[0] = diff_api.Disable;
927 able[1] = diff_api.Enable;
928 if (from->stencilTest != to->stencilTest)
929 {
930 able[to->stencilTest](GL_STENCIL_TEST);
931 FILLDIRTY(b->enable);
932 FILLDIRTY(b->dirty);
933 }
934 CLEARDIRTY(b->enable, nbitID);
935 }
936 if (CHECKDIRTY(b->enableTwoSideEXT, bitID))
937 {
938 glAble able[2];
939 able[0] = diff_api.Disable;
940 able[1] = diff_api.Enable;
941 if (from->stencilTwoSideEXT != to->stencilTwoSideEXT)
942 {
943 able[to->stencilTwoSideEXT](GL_STENCIL_TEST_TWO_SIDE_EXT);
944 FILLDIRTY(b->enableTwoSideEXT);
945 FILLDIRTY(b->dirty);
946 }
947 CLEARDIRTY(b->enableTwoSideEXT, nbitID);
948 }
949 if (CHECKDIRTY(b->clearValue, bitID))
950 {
951 if (from->clearValue != to->clearValue)
952 {
953 diff_api.ClearStencil (to->clearValue);
954 FILLDIRTY(b->clearValue);
955 FILLDIRTY(b->dirty);
956 }
957 CLEARDIRTY(b->clearValue, nbitID);
958 }
959
960 activeFace = from->activeStencilFace;
961
962 /* func */
963 frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, bitID);
964 frontDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func, bitID);
965 backDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func, bitID);
966#define CR_STATE_STENCIL_FUNC_FRONT_MATCH() ( \
967 frontMatch >= 0 ? \
968 frontMatch \
969 : (frontMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
970
971#define CR_STATE_STENCIL_FUNC_BACK_MATCH() ( \
972 backMatch >= 0 ? \
973 backMatch \
974 : (backMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
975
976#define CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH() ( \
977 toFrontBackMatch >= 0 ? \
978 toFrontBackMatch \
979 : (toFrontBackMatch = CR_STATE_STENCIL_FUNC_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
980
981 if (frontBackDirty)
982 {
983 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH()
984 || !CR_STATE_STENCIL_FUNC_BACK_MATCH())
985 {
986 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
987 {
988 if (activeFace == GL_BACK)
989 {
990 diff_api.ActiveStencilFaceEXT(GL_FRONT);
991 activeFace = GL_FRONT;
992 }
993
994 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
995 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
996 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
997
998 frontIsSet = GL_TRUE;
999 backIsSet = GL_TRUE;
1000 }
1001 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
1002 {
1003 if (activeFace == GL_BACK)
1004 {
1005 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1006 activeFace = GL_FRONT;
1007 }
1008
1009 diff_api.StencilFuncSeparate (GL_FRONT, 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 frontIsSet = GL_TRUE;
1013 }
1014 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
1015 {
1016 if (activeFace == GL_BACK)
1017 {
1018 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1019 activeFace = GL_FRONT;
1020 }
1021
1022 diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
1023 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
1024 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask);
1025 backIsSet = GL_TRUE;
1026 }
1027 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func);
1028 FILLDIRTY(b->dirty);
1029 }
1030
1031 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, nbitID);
1032 }
1033
1034 if (frontDirty)
1035 {
1036 if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
1037 {
1038 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
1039 {
1040 if (!frontIsSet || !backIsSet)
1041 {
1042 if (activeFace == GL_BACK)
1043 {
1044 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1045 activeFace = GL_FRONT;
1046 }
1047
1048 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1049 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1050 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
1051
1052 frontIsSet = GL_TRUE;
1053 backIsSet = GL_TRUE;
1054 }
1055 }
1056 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
1057 {
1058 if (!frontIsSet)
1059 {
1060 if (activeFace == GL_BACK)
1061 {
1062 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1063 activeFace = GL_FRONT;
1064 }
1065
1066 diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1067 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1068 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
1069 frontIsSet = GL_TRUE;
1070 }
1071 }
1072 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
1073 {
1074 if (!backIsSet)
1075 {
1076 if (activeFace == GL_BACK)
1077 {
1078 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1079 activeFace = GL_FRONT;
1080 }
1081
1082 diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
1083 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
1084 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask);
1085 backIsSet = GL_TRUE;
1086 }
1087 }
1088 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func);
1089 FILLDIRTY(b->dirty);
1090 }
1091 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func, nbitID);
1092 }
1093
1094
1095 if (backDirty)
1096 {
1097 if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
1098 {
1099 if (CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH())
1100 {
1101 if (!frontIsSet || !backIsSet)
1102 {
1103 if (activeFace == GL_BACK)
1104 {
1105 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1106 activeFace = GL_FRONT;
1107 }
1108
1109 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1110 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1111 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
1112
1113 frontIsSet = GL_TRUE;
1114 backIsSet = GL_TRUE;
1115 }
1116 }
1117 else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
1118 {
1119 if (!frontIsSet)
1120 {
1121 if (activeFace == GL_BACK)
1122 {
1123 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1124 activeFace = GL_FRONT;
1125 }
1126
1127 diff_api.StencilFuncSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func,
1128 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref,
1129 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask);
1130 frontIsSet = GL_TRUE;
1131 }
1132 }
1133 else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
1134 {
1135 if (!backIsSet)
1136 {
1137 if (activeFace == GL_BACK)
1138 {
1139 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1140 activeFace = GL_FRONT;
1141 }
1142
1143 diff_api.StencilFuncSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func,
1144 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref,
1145 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask);
1146 backIsSet = GL_TRUE;
1147 }
1148 }
1149 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func);
1150 FILLDIRTY(b->dirty);
1151 }
1152 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func, nbitID);
1153 }
1154
1155 if (CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func, bitID))
1156 {
1157 if (CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK))
1158 {
1159 if (activeFace == GL_FRONT)
1160 {
1161 diff_api.ActiveStencilFaceEXT(GL_BACK);
1162 activeFace = GL_BACK;
1163 }
1164
1165 diff_api.StencilFunc (to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func,
1166 to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].ref,
1167 to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].mask);
1168
1169 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func);
1170 FILLDIRTY(b->dirty);
1171 }
1172 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].func, nbitID);
1173 }
1174
1175#undef CR_STATE_STENCIL_FUNC_FRONT_MATCH
1176#undef CR_STATE_STENCIL_FUNC_BACK_MATCH
1177#undef CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH
1178
1179 /* op */
1180 backIsSet = GL_FALSE, frontIsSet = GL_FALSE;
1181 frontMatch = -1, backMatch = -1, toFrontBackMatch = -1;
1182 frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op, bitID);
1183 frontDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op, bitID);
1184 backDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op, bitID);
1185
1186#define CR_STATE_STENCIL_OP_FRONT_MATCH() ( \
1187 frontMatch >= 0 ? \
1188 frontMatch \
1189 : (frontMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
1190
1191#define CR_STATE_STENCIL_OP_BACK_MATCH() ( \
1192 backMatch >= 0 ? \
1193 backMatch \
1194 : (backMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
1195
1196#define CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH() ( \
1197 toFrontBackMatch >= 0 ? \
1198 toFrontBackMatch \
1199 : (toFrontBackMatch = CR_STATE_STENCIL_OP_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
1200
1201 if (frontBackDirty)
1202 {
1203 if (!CR_STATE_STENCIL_OP_FRONT_MATCH()
1204 || !CR_STATE_STENCIL_OP_BACK_MATCH())
1205 {
1206 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
1207 {
1208 if (activeFace == GL_BACK)
1209 {
1210 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1211 activeFace = GL_FRONT;
1212 }
1213
1214 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1215 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1216 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
1217
1218 frontIsSet = GL_TRUE;
1219 backIsSet = GL_TRUE;
1220 }
1221 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
1222 {
1223 if (activeFace == GL_BACK)
1224 {
1225 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1226 activeFace = GL_FRONT;
1227 }
1228
1229 diff_api.StencilOpSeparate (GL_FRONT, 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 frontIsSet = GL_TRUE;
1233 }
1234 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
1235 {
1236 if (activeFace == GL_BACK)
1237 {
1238 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1239 activeFace = GL_FRONT;
1240 }
1241
1242 diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
1243 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
1244 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass);
1245 backIsSet = GL_TRUE;
1246 }
1247 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op);
1248 FILLDIRTY(b->dirty);
1249 }
1250
1251 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op, nbitID);
1252 }
1253
1254 if (frontDirty)
1255 {
1256 if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
1257 {
1258 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
1259 {
1260 if (!frontIsSet || !backIsSet)
1261 {
1262 if (activeFace == GL_BACK)
1263 {
1264 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1265 activeFace = GL_FRONT;
1266 }
1267
1268 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1269 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1270 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
1271
1272 frontIsSet = GL_TRUE;
1273 backIsSet = GL_TRUE;
1274 }
1275 }
1276 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
1277 {
1278 if (!frontIsSet)
1279 {
1280 if (activeFace == GL_BACK)
1281 {
1282 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1283 activeFace = GL_FRONT;
1284 }
1285
1286 diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1287 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1288 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
1289 frontIsSet = GL_TRUE;
1290 }
1291 }
1292 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
1293 {
1294 if (!backIsSet)
1295 {
1296 if (activeFace == GL_BACK)
1297 {
1298 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1299 activeFace = GL_FRONT;
1300 }
1301
1302 diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
1303 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
1304 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass);
1305 backIsSet = GL_TRUE;
1306 }
1307 }
1308
1309 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op);
1310 FILLDIRTY(b->dirty);
1311 }
1312 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op, nbitID);
1313 }
1314
1315
1316 if (backDirty)
1317 {
1318 if (!CR_STATE_STENCIL_OP_BACK_MATCH())
1319 {
1320 if (CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH())
1321 {
1322 if (!frontIsSet || !backIsSet)
1323 {
1324 if (activeFace == GL_BACK)
1325 {
1326 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1327 activeFace = GL_FRONT;
1328 }
1329
1330 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1331 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1332 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
1333
1334 frontIsSet = GL_TRUE;
1335 backIsSet = GL_TRUE;
1336 }
1337 }
1338 else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
1339 {
1340 if (!frontIsSet)
1341 {
1342 if (activeFace == GL_BACK)
1343 {
1344 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1345 activeFace = GL_FRONT;
1346 }
1347
1348 diff_api.StencilOpSeparate (GL_FRONT, to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail,
1349 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail,
1350 to->buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass);
1351 frontIsSet = GL_TRUE;
1352 }
1353 }
1354 else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
1355 {
1356 if (!backIsSet)
1357 {
1358 if (activeFace == GL_BACK)
1359 {
1360 diff_api.ActiveStencilFaceEXT(GL_FRONT);
1361 activeFace = GL_FRONT;
1362 }
1363
1364 diff_api.StencilOpSeparate (GL_BACK, to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail,
1365 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail,
1366 to->buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass);
1367 backIsSet = GL_TRUE;
1368 }
1369 }
1370
1371 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op);
1372 FILLDIRTY(b->dirty);
1373 }
1374 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op, nbitID);
1375 }
1376
1377 if (CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op, bitID))
1378 {
1379 if (CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK))
1380 {
1381 if (activeFace == GL_FRONT)
1382 {
1383 diff_api.ActiveStencilFaceEXT(GL_BACK);
1384 activeFace = GL_BACK;
1385 }
1386
1387 diff_api.StencilOp (to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].fail,
1388 to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].passDepthFail,
1389 to->buffers[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].passDepthPass);
1390
1391 FILLDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op);
1392 FILLDIRTY(b->dirty);
1393 }
1394 CLEARDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK].op, nbitID);
1395 }
1396
1397#undef CR_STATE_STENCIL_OP_FRONT_MATCH
1398#undef CR_STATE_STENCIL_OP_BACK_MATCH
1399#undef CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH
1400
1401 if (activeFace != to->activeStencilFace)
1402 {
1403 diff_api.ActiveStencilFaceEXT(activeFace);
1404 }
1405
1406 if (CHECKDIRTY(b->activeStencilFace, bitID))
1407 {
1408 if (from->activeStencilFace != to->activeStencilFace)
1409 {
1410 /* we already did it ( see above )*/
1411 /* diff_api.ActiveStencilFaceEXT(to->activeStencilFace); */
1412 FILLDIRTY(b->activeStencilFace);
1413 FILLDIRTY(b->dirty);
1414 }
1415 CLEARDIRTY(b->activeStencilFace, nbitID);
1416 }
1417
1418 if (CHECKDIRTY(b->writeMask, bitID))
1419 {
1420 if (from->writeMask != to->writeMask)
1421 {
1422 diff_api.StencilMask (to->writeMask);
1423 FILLDIRTY(b->writeMask);
1424 FILLDIRTY(b->dirty);
1425 }
1426 CLEARDIRTY(b->writeMask, nbitID);
1427 }
1428
1429 CLEARDIRTY(b->dirty, nbitID);
1430}
1431
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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