stencil.c revision 1d5e49bf05f698374257707e2303b266d2a864da
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.1 4 * 5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26/** 27 * \file stencil.c 28 * Stencil operations. 29 * 30 * Note: There's some conflict between GL_EXT_stencil_two_side and 31 * OpenGL 2.0's two-sided stencil feature. 32 * 33 * With GL_EXT_stencil_two_side, calling glStencilOp/Func/Mask() only the 34 * front OR back face state (as set by glActiveStencilFaceEXT) is set. 35 * 36 * But with OpenGL 2.0, calling glStencilOp/Func/Mask() sets BOTH the 37 * front AND back state. 38 * 39 * Also, note that GL_ATI_separate_stencil is different as well: 40 * glStencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, ...) vs. 41 * glStencilFuncSeparate(GLenum face, GLenum func, ...). 42 * 43 * This problem is solved by keeping three sets of stencil state: 44 * state[0] = GL_FRONT state. 45 * state[1] = OpenGL 2.0 / GL_ATI_separate_stencil GL_BACK state. 46 * state[2] = GL_EXT_stencil_two_side GL_BACK state. 47 */ 48 49 50#include "glheader.h" 51#include "imports.h" 52#include "context.h" 53#include "macros.h" 54#include "stencil.h" 55#include "mtypes.h" 56 57 58static GLboolean 59validate_stencil_op(struct gl_context *ctx, GLenum op) 60{ 61 switch (op) { 62 case GL_KEEP: 63 case GL_ZERO: 64 case GL_REPLACE: 65 case GL_INCR: 66 case GL_DECR: 67 case GL_INVERT: 68 case GL_INCR_WRAP: 69 case GL_DECR_WRAP: 70 return GL_TRUE; 71 default: 72 return GL_FALSE; 73 } 74} 75 76 77static GLboolean 78validate_stencil_func(struct gl_context *ctx, GLenum func) 79{ 80 switch (func) { 81 case GL_NEVER: 82 case GL_LESS: 83 case GL_LEQUAL: 84 case GL_GREATER: 85 case GL_GEQUAL: 86 case GL_EQUAL: 87 case GL_NOTEQUAL: 88 case GL_ALWAYS: 89 return GL_TRUE; 90 default: 91 return GL_FALSE; 92 } 93} 94 95 96/** 97 * Set the clear value for the stencil buffer. 98 * 99 * \param s clear value. 100 * 101 * \sa glClearStencil(). 102 * 103 * Updates gl_stencil_attrib::Clear. On change 104 * flushes the vertices and notifies the driver via 105 * the dd_function_table::ClearStencil callback. 106 */ 107void GLAPIENTRY 108_mesa_ClearStencil( GLint s ) 109{ 110 GET_CURRENT_CONTEXT(ctx); 111 ASSERT_OUTSIDE_BEGIN_END(ctx); 112 113 if (ctx->Stencil.Clear == (GLuint) s) 114 return; 115 116 FLUSH_VERTICES(ctx, _NEW_STENCIL); 117 ctx->Stencil.Clear = (GLuint) s; 118 119 if (ctx->Driver.ClearStencil) { 120 ctx->Driver.ClearStencil( ctx, s ); 121 } 122} 123 124 125/** 126 * Set the function and reference value for stencil testing. 127 * 128 * \param frontfunc front test function. 129 * \param backfunc back test function. 130 * \param ref front and back reference value. 131 * \param mask front and back bitmask. 132 * 133 * \sa glStencilFunc(). 134 * 135 * Verifies the parameters and updates the respective values in 136 * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the 137 * driver via the dd_function_table::StencilFunc callback. 138 */ 139void GLAPIENTRY 140_mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask ) 141{ 142 GET_CURRENT_CONTEXT(ctx); 143 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 144 ASSERT_OUTSIDE_BEGIN_END(ctx); 145 146 if (MESA_VERBOSE & VERBOSE_API) 147 _mesa_debug(ctx, "glStencilFuncSeparateATI()\n"); 148 149 if (!validate_stencil_func(ctx, frontfunc)) { 150 _mesa_error(ctx, GL_INVALID_ENUM, 151 "glStencilFuncSeparateATI(frontfunc)"); 152 return; 153 } 154 if (!validate_stencil_func(ctx, backfunc)) { 155 _mesa_error(ctx, GL_INVALID_ENUM, 156 "glStencilFuncSeparateATI(backfunc)"); 157 return; 158 } 159 160 ref = CLAMP( ref, 0, stencilMax ); 161 162 /* set both front and back state */ 163 if (ctx->Stencil.Function[0] == frontfunc && 164 ctx->Stencil.Function[1] == backfunc && 165 ctx->Stencil.ValueMask[0] == mask && 166 ctx->Stencil.ValueMask[1] == mask && 167 ctx->Stencil.Ref[0] == ref && 168 ctx->Stencil.Ref[1] == ref) 169 return; 170 FLUSH_VERTICES(ctx, _NEW_STENCIL); 171 ctx->Stencil.Function[0] = frontfunc; 172 ctx->Stencil.Function[1] = backfunc; 173 ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref; 174 ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask; 175 if (ctx->Driver.StencilFuncSeparate) { 176 ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, 177 frontfunc, ref, mask); 178 ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, 179 backfunc, ref, mask); 180 } 181} 182 183 184/** 185 * Set the function and reference value for stencil testing. 186 * 187 * \param func test function. 188 * \param ref reference value. 189 * \param mask bitmask. 190 * 191 * \sa glStencilFunc(). 192 * 193 * Verifies the parameters and updates the respective values in 194 * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the 195 * driver via the dd_function_table::StencilFunc callback. 196 */ 197void GLAPIENTRY 198_mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) 199{ 200 GET_CURRENT_CONTEXT(ctx); 201 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 202 const GLint face = ctx->Stencil.ActiveFace; 203 ASSERT_OUTSIDE_BEGIN_END(ctx); 204 205 if (MESA_VERBOSE & VERBOSE_API) 206 _mesa_debug(ctx, "glStencilFunc()\n"); 207 208 if (!validate_stencil_func(ctx, func)) { 209 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFunc(func)"); 210 return; 211 } 212 213 ref = CLAMP( ref, 0, stencilMax ); 214 215 if (face != 0) { 216 if (ctx->Stencil.Function[face] == func && 217 ctx->Stencil.ValueMask[face] == mask && 218 ctx->Stencil.Ref[face] == ref) 219 return; 220 FLUSH_VERTICES(ctx, _NEW_STENCIL); 221 ctx->Stencil.Function[face] = func; 222 ctx->Stencil.Ref[face] = ref; 223 ctx->Stencil.ValueMask[face] = mask; 224 225 /* Only propagate the change to the driver if EXT_stencil_two_side 226 * is enabled. 227 */ 228 if (ctx->Driver.StencilFuncSeparate && ctx->Stencil.TestTwoSide) { 229 ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, func, ref, mask); 230 } 231 } 232 else { 233 /* set both front and back state */ 234 if (ctx->Stencil.Function[0] == func && 235 ctx->Stencil.Function[1] == func && 236 ctx->Stencil.ValueMask[0] == mask && 237 ctx->Stencil.ValueMask[1] == mask && 238 ctx->Stencil.Ref[0] == ref && 239 ctx->Stencil.Ref[1] == ref) 240 return; 241 FLUSH_VERTICES(ctx, _NEW_STENCIL); 242 ctx->Stencil.Function[0] = ctx->Stencil.Function[1] = func; 243 ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref; 244 ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask; 245 if (ctx->Driver.StencilFuncSeparate) { 246 ctx->Driver.StencilFuncSeparate(ctx, 247 ((ctx->Stencil.TestTwoSide) 248 ? GL_FRONT : GL_FRONT_AND_BACK), 249 func, ref, mask); 250 } 251 } 252} 253 254 255/** 256 * Set the stencil writing mask. 257 * 258 * \param mask bit-mask to enable/disable writing of individual bits in the 259 * stencil planes. 260 * 261 * \sa glStencilMask(). 262 * 263 * Updates gl_stencil_attrib::WriteMask. On change flushes the vertices and 264 * notifies the driver via the dd_function_table::StencilMask callback. 265 */ 266void GLAPIENTRY 267_mesa_StencilMask( GLuint mask ) 268{ 269 GET_CURRENT_CONTEXT(ctx); 270 const GLint face = ctx->Stencil.ActiveFace; 271 272 if (MESA_VERBOSE & VERBOSE_API) 273 _mesa_debug(ctx, "glStencilMask()\n"); 274 275 ASSERT_OUTSIDE_BEGIN_END(ctx); 276 277 if (face != 0) { 278 /* Only modify the EXT_stencil_two_side back-face state. 279 */ 280 if (ctx->Stencil.WriteMask[face] == mask) 281 return; 282 FLUSH_VERTICES(ctx, _NEW_STENCIL); 283 ctx->Stencil.WriteMask[face] = mask; 284 285 /* Only propagate the change to the driver if EXT_stencil_two_side 286 * is enabled. 287 */ 288 if (ctx->Driver.StencilMaskSeparate && ctx->Stencil.TestTwoSide) { 289 ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, mask); 290 } 291 } 292 else { 293 /* set both front and back state */ 294 if (ctx->Stencil.WriteMask[0] == mask && 295 ctx->Stencil.WriteMask[1] == mask) 296 return; 297 FLUSH_VERTICES(ctx, _NEW_STENCIL); 298 ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask; 299 if (ctx->Driver.StencilMaskSeparate) { 300 ctx->Driver.StencilMaskSeparate(ctx, 301 ((ctx->Stencil.TestTwoSide) 302 ? GL_FRONT : GL_FRONT_AND_BACK), 303 mask); 304 } 305 } 306} 307 308 309/** 310 * Set the stencil test actions. 311 * 312 * \param fail action to take when stencil test fails. 313 * \param zfail action to take when stencil test passes, but depth test fails. 314 * \param zpass action to take when stencil test passes and the depth test 315 * passes (or depth testing is not enabled). 316 * 317 * \sa glStencilOp(). 318 * 319 * Verifies the parameters and updates the respective fields in 320 * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the 321 * driver via the dd_function_table::StencilOp callback. 322 */ 323void GLAPIENTRY 324_mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) 325{ 326 GET_CURRENT_CONTEXT(ctx); 327 const GLint face = ctx->Stencil.ActiveFace; 328 329 if (MESA_VERBOSE & VERBOSE_API) 330 _mesa_debug(ctx, "glStencilOp()\n"); 331 332 ASSERT_OUTSIDE_BEGIN_END(ctx); 333 334 if (!validate_stencil_op(ctx, fail)) { 335 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(sfail)"); 336 return; 337 } 338 if (!validate_stencil_op(ctx, zfail)) { 339 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zfail)"); 340 return; 341 } 342 if (!validate_stencil_op(ctx, zpass)) { 343 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zpass)"); 344 return; 345 } 346 347 if (face != 0) { 348 /* only set active face state */ 349 if (ctx->Stencil.ZFailFunc[face] == zfail && 350 ctx->Stencil.ZPassFunc[face] == zpass && 351 ctx->Stencil.FailFunc[face] == fail) 352 return; 353 FLUSH_VERTICES(ctx, _NEW_STENCIL); 354 ctx->Stencil.ZFailFunc[face] = zfail; 355 ctx->Stencil.ZPassFunc[face] = zpass; 356 ctx->Stencil.FailFunc[face] = fail; 357 358 /* Only propagate the change to the driver if EXT_stencil_two_side 359 * is enabled. 360 */ 361 if (ctx->Driver.StencilOpSeparate && ctx->Stencil.TestTwoSide) { 362 ctx->Driver.StencilOpSeparate(ctx, GL_BACK, fail, zfail, zpass); 363 } 364 } 365 else { 366 /* set both front and back state */ 367 if (ctx->Stencil.ZFailFunc[0] == zfail && 368 ctx->Stencil.ZFailFunc[1] == zfail && 369 ctx->Stencil.ZPassFunc[0] == zpass && 370 ctx->Stencil.ZPassFunc[1] == zpass && 371 ctx->Stencil.FailFunc[0] == fail && 372 ctx->Stencil.FailFunc[1] == fail) 373 return; 374 FLUSH_VERTICES(ctx, _NEW_STENCIL); 375 ctx->Stencil.ZFailFunc[0] = ctx->Stencil.ZFailFunc[1] = zfail; 376 ctx->Stencil.ZPassFunc[0] = ctx->Stencil.ZPassFunc[1] = zpass; 377 ctx->Stencil.FailFunc[0] = ctx->Stencil.FailFunc[1] = fail; 378 if (ctx->Driver.StencilOpSeparate) { 379 ctx->Driver.StencilOpSeparate(ctx, 380 ((ctx->Stencil.TestTwoSide) 381 ? GL_FRONT : GL_FRONT_AND_BACK), 382 fail, zfail, zpass); 383 } 384 } 385} 386 387 388 389#if _HAVE_FULL_GL 390/* GL_EXT_stencil_two_side */ 391void GLAPIENTRY 392_mesa_ActiveStencilFaceEXT(GLenum face) 393{ 394 GET_CURRENT_CONTEXT(ctx); 395 ASSERT_OUTSIDE_BEGIN_END(ctx); 396 397 if (MESA_VERBOSE & VERBOSE_API) 398 _mesa_debug(ctx, "glActiveStencilFaceEXT()\n"); 399 400 if (!ctx->Extensions.EXT_stencil_two_side) { 401 _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveStencilFaceEXT"); 402 return; 403 } 404 405 if (face == GL_FRONT || face == GL_BACK) { 406 FLUSH_VERTICES(ctx, _NEW_STENCIL); 407 ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 2; 408 } 409 else { 410 _mesa_error(ctx, GL_INVALID_ENUM, "glActiveStencilFaceEXT(face)"); 411 } 412} 413#endif 414 415 416 417/** 418 * OpenGL 2.0 function. 419 * \todo Make StencilOp() call this function. And eventually remove the 420 * ctx->Driver.StencilOp function and use ctx->Driver.StencilOpSeparate 421 * instead. 422 */ 423void GLAPIENTRY 424_mesa_StencilOpSeparate(GLenum face, GLenum sfail, GLenum zfail, GLenum zpass) 425{ 426 GLboolean set = GL_FALSE; 427 GET_CURRENT_CONTEXT(ctx); 428 ASSERT_OUTSIDE_BEGIN_END(ctx); 429 430 if (MESA_VERBOSE & VERBOSE_API) 431 _mesa_debug(ctx, "glStencilOpSeparate()\n"); 432 433 if (!validate_stencil_op(ctx, sfail)) { 434 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(sfail)"); 435 return; 436 } 437 if (!validate_stencil_op(ctx, zfail)) { 438 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)"); 439 return; 440 } 441 if (!validate_stencil_op(ctx, zpass)) { 442 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)"); 443 return; 444 } 445 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { 446 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(face)"); 447 return; 448 } 449 450 if (face != GL_BACK) { 451 /* set front */ 452 if (ctx->Stencil.ZFailFunc[0] != zfail || 453 ctx->Stencil.ZPassFunc[0] != zpass || 454 ctx->Stencil.FailFunc[0] != sfail){ 455 FLUSH_VERTICES(ctx, _NEW_STENCIL); 456 ctx->Stencil.ZFailFunc[0] = zfail; 457 ctx->Stencil.ZPassFunc[0] = zpass; 458 ctx->Stencil.FailFunc[0] = sfail; 459 set = GL_TRUE; 460 } 461 } 462 if (face != GL_FRONT) { 463 /* set back */ 464 if (ctx->Stencil.ZFailFunc[1] != zfail || 465 ctx->Stencil.ZPassFunc[1] != zpass || 466 ctx->Stencil.FailFunc[1] != sfail) { 467 FLUSH_VERTICES(ctx, _NEW_STENCIL); 468 ctx->Stencil.ZFailFunc[1] = zfail; 469 ctx->Stencil.ZPassFunc[1] = zpass; 470 ctx->Stencil.FailFunc[1] = sfail; 471 set = GL_TRUE; 472 } 473 } 474 if (set && ctx->Driver.StencilOpSeparate) { 475 ctx->Driver.StencilOpSeparate(ctx, face, sfail, zfail, zpass); 476 } 477} 478 479 480/* OpenGL 2.0 */ 481void GLAPIENTRY 482_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) 483{ 484 GET_CURRENT_CONTEXT(ctx); 485 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 486 ASSERT_OUTSIDE_BEGIN_END(ctx); 487 488 if (MESA_VERBOSE & VERBOSE_API) 489 _mesa_debug(ctx, "glStencilFuncSeparate()\n"); 490 491 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { 492 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(face)"); 493 return; 494 } 495 if (!validate_stencil_func(ctx, func)) { 496 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)"); 497 return; 498 } 499 500 ref = CLAMP(ref, 0, stencilMax); 501 502 FLUSH_VERTICES(ctx, _NEW_STENCIL); 503 504 if (face != GL_BACK) { 505 /* set front */ 506 ctx->Stencil.Function[0] = func; 507 ctx->Stencil.Ref[0] = ref; 508 ctx->Stencil.ValueMask[0] = mask; 509 } 510 if (face != GL_FRONT) { 511 /* set back */ 512 ctx->Stencil.Function[1] = func; 513 ctx->Stencil.Ref[1] = ref; 514 ctx->Stencil.ValueMask[1] = mask; 515 } 516 if (ctx->Driver.StencilFuncSeparate) { 517 ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask); 518 } 519} 520 521 522/* OpenGL 2.0 */ 523void GLAPIENTRY 524_mesa_StencilMaskSeparate(GLenum face, GLuint mask) 525{ 526 GET_CURRENT_CONTEXT(ctx); 527 ASSERT_OUTSIDE_BEGIN_END(ctx); 528 529 if (MESA_VERBOSE & VERBOSE_API) 530 _mesa_debug(ctx, "glStencilMaskSeparate()\n"); 531 532 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { 533 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilaMaskSeparate(face)"); 534 return; 535 } 536 537 FLUSH_VERTICES(ctx, _NEW_STENCIL); 538 539 if (face != GL_BACK) { 540 ctx->Stencil.WriteMask[0] = mask; 541 } 542 if (face != GL_FRONT) { 543 ctx->Stencil.WriteMask[1] = mask; 544 } 545 if (ctx->Driver.StencilMaskSeparate) { 546 ctx->Driver.StencilMaskSeparate(ctx, face, mask); 547 } 548} 549 550 551/** 552 * Update derived stencil state. 553 */ 554void 555_mesa_update_stencil(struct gl_context *ctx) 556{ 557 const GLint face = ctx->Stencil._BackFace; 558 559 ctx->Stencil._Enabled = (ctx->Stencil.Enabled && 560 ctx->DrawBuffer->Visual.stencilBits > 0); 561 562 ctx->Stencil._TestTwoSide = 563 ctx->Stencil._Enabled && 564 (ctx->Stencil.Function[0] != ctx->Stencil.Function[face] || 565 ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[face] || 566 ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[face] || 567 ctx->Stencil.ZFailFunc[0] != ctx->Stencil.ZFailFunc[face] || 568 ctx->Stencil.Ref[0] != ctx->Stencil.Ref[face] || 569 ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[face] || 570 ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[face]); 571} 572 573 574/** 575 * Initialize the context stipple state. 576 * 577 * \param ctx GL context. 578 * 579 * Initializes __struct gl_contextRec::Stencil attribute group. 580 */ 581void 582_mesa_init_stencil(struct gl_context *ctx) 583{ 584 ctx->Stencil.Enabled = GL_FALSE; 585 ctx->Stencil.TestTwoSide = GL_FALSE; 586 ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 2 = GL_BACK */ 587 ctx->Stencil.Function[0] = GL_ALWAYS; 588 ctx->Stencil.Function[1] = GL_ALWAYS; 589 ctx->Stencil.Function[2] = GL_ALWAYS; 590 ctx->Stencil.FailFunc[0] = GL_KEEP; 591 ctx->Stencil.FailFunc[1] = GL_KEEP; 592 ctx->Stencil.FailFunc[2] = GL_KEEP; 593 ctx->Stencil.ZPassFunc[0] = GL_KEEP; 594 ctx->Stencil.ZPassFunc[1] = GL_KEEP; 595 ctx->Stencil.ZPassFunc[2] = GL_KEEP; 596 ctx->Stencil.ZFailFunc[0] = GL_KEEP; 597 ctx->Stencil.ZFailFunc[1] = GL_KEEP; 598 ctx->Stencil.ZFailFunc[2] = GL_KEEP; 599 ctx->Stencil.Ref[0] = 0; 600 ctx->Stencil.Ref[1] = 0; 601 ctx->Stencil.Ref[2] = 0; 602 ctx->Stencil.ValueMask[0] = ~0U; 603 ctx->Stencil.ValueMask[1] = ~0U; 604 ctx->Stencil.ValueMask[2] = ~0U; 605 ctx->Stencil.WriteMask[0] = ~0U; 606 ctx->Stencil.WriteMask[1] = ~0U; 607 ctx->Stencil.WriteMask[2] = ~0U; 608 ctx->Stencil.Clear = 0; 609 ctx->Stencil._BackFace = 1; 610} 611