Changeset 44326 in vbox for trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_stencil.c
- Timestamp:
- Jan 22, 2013 8:18:51 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_stencil.c
r15532 r44326 10 10 #include "state_internals.h" 11 11 12 13 static 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 48 void 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 59 static void crStateStencilBufferRefBitsInit(CRContext *ctx, CRStencilBufferRefBits *sb) 60 { 61 RESET(sb->func, ctx->bitid); 62 RESET(sb->op, ctx->bitid); 63 } 64 12 65 void crStateStencilInit(CRContext *ctx) 13 66 { … … 15 68 CRStateBits *stateb = GetCurrentBits(); 16 69 CRStencilBits *sb = &(stateb->stencil); 70 int i; 17 71 18 72 s->stencilTest = GL_FALSE; 19 73 RESET(sb->enable, ctx->bitid); 20 74 21 s->func = GL_ALWAYS; 22 s->mask = 0xFFFFFFFF; 23 s->ref = 0; 24 RESET(sb->func, ctx->bitid); 25 26 s->fail = GL_KEEP; 27 s->passDepthFail = GL_KEEP; 28 s->passDepthPass = GL_KEEP; 29 RESET(sb->op, ctx->bitid); 75 s->stencilTwoSideEXT = GL_FALSE; 76 RESET(sb->enableTwoSideEXT, ctx->bitid); 77 78 s->activeStencilFace = GL_FRONT; 79 RESET(sb->activeStencilFace, ctx->bitid); 30 80 31 81 s->clearValue = 0; … … 36 86 37 87 RESET(sb->dirty, ctx->bitid); 38 } 39 40 void STATE_APIENTRY crStateStencilFunc(GLenum func, GLint ref, GLuint mask) 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 100 static 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 107 static 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 152 void 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 164 void STATE_APIENTRY crStateStencilFunc(GLenum func, GLint ref, GLuint mask) 165 { 166 crStateStencilFuncPerform(0, func, ref, mask); 167 } 168 169 static 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 176 static void crStateStencilOpPerform (GLenum face, GLenum fail, GLenum zfail, GLenum zpass) 41 177 { 42 178 CRContext *g = GetCurrentContext(); … … 44 180 CRStateBits *stateb = GetCurrentBits(); 45 181 CRStencilBits *sb = &(stateb->stencil); 46 47 48 if (g->current.inBeginEnd) 49 { 50 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, 51 "glStencilFunc called in begin/end"); 52 return; 53 } 54 55 FLUSH(); 56 57 if (func != GL_NEVER && 58 func != GL_LESS && 59 func != GL_LEQUAL && 60 func != GL_GREATER && 61 func != GL_GEQUAL && 62 func != GL_EQUAL && 63 func != GL_NOTEQUAL && 64 func != GL_ALWAYS) 65 { 66 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, 67 "glStencilFunc called with bogu func: %d", func); 68 return; 69 } 70 71 s->func = func; 72 s->ref = ref; 73 s->mask = mask; 74 75 DIRTY(sb->func, g->neg_bitid); 76 DIRTY(sb->dirty, g->neg_bitid); 77 } 78 79 void STATE_APIENTRY crStateStencilOp (GLenum fail, GLenum zfail, GLenum zpass) 80 { 81 CRContext *g = GetCurrentContext(); 82 CRStencilState *s = &(g->stencil); 83 CRStateBits *stateb = GetCurrentBits(); 84 CRStencilBits *sb = &(stateb->stencil); 182 GLint idx, bitsIdx, count, i; 85 183 86 184 if (g->current.inBeginEnd) … … 147 245 } 148 246 149 s->fail = fail; 150 s->passDepthFail = zfail; 151 s->passDepthPass = zpass; 152 153 DIRTY(sb->op, g->neg_bitid); 154 DIRTY(sb->dirty, g->neg_bitid); 155 } 156 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 261 void 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 273 void STATE_APIENTRY crStateStencilOp (GLenum fail, GLenum zfail, GLenum zpass) 274 { 275 crStateStencilOpPerform (0, fail, zfail, zpass); 276 } 157 277 158 278 void STATE_APIENTRY crStateClearStencil (GLint c) … … 172 292 FLUSH(); 173 293 174 175 294 s->clearValue = c; 176 295 … … 200 319 DIRTY(sb->dirty, g->neg_bitid); 201 320 } 321 322 void 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 368 void 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 909 void 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
Note:
See TracChangeset
for help on using the changeset viewer.