📄 stencil.c
字号:
return; FLUSH_VERTICES(ctx, _NEW_STENCIL); ctx->Stencil.ZFailFunc[face] = zfail; ctx->Stencil.ZPassFunc[face] = zpass; ctx->Stencil.FailFunc[face] = fail; if (ctx->Driver.StencilOpSeparate) { ctx->Driver.StencilOpSeparate(ctx, face ? GL_BACK : GL_FRONT, fail, zfail, zpass); } } else { /* set both front and back state */ if (ctx->Stencil.ZFailFunc[0] == zfail && ctx->Stencil.ZFailFunc[1] == zfail && ctx->Stencil.ZPassFunc[0] == zpass && ctx->Stencil.ZPassFunc[1] == zpass && ctx->Stencil.FailFunc[0] == fail && ctx->Stencil.FailFunc[1] == fail) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); ctx->Stencil.ZFailFunc[0] = ctx->Stencil.ZFailFunc[1] = zfail; ctx->Stencil.ZPassFunc[0] = ctx->Stencil.ZPassFunc[1] = zpass; ctx->Stencil.FailFunc[0] = ctx->Stencil.FailFunc[1] = fail; if (ctx->Driver.StencilOpSeparate) { ctx->Driver.StencilOpSeparate(ctx, GL_FRONT_AND_BACK, fail, zfail, zpass); } }}#if _HAVE_FULL_GL/* GL_EXT_stencil_two_side */void GLAPIENTRY_mesa_ActiveStencilFaceEXT(GLenum face){ GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (!ctx->Extensions.EXT_stencil_two_side) { _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveStencilFaceEXT"); return; } if (face == GL_FRONT || face == GL_BACK) { FLUSH_VERTICES(ctx, _NEW_STENCIL); ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 1; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glActiveStencilFaceEXT(face)"); }}#endif/** * OpenGL 2.0 function. * \todo Make StencilOp() call this function. And eventually remove the * ctx->Driver.StencilOp function and use ctx->Driver.StencilOpSeparate * instead. */void GLAPIENTRY_mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass){ GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(face)"); return; } switch (fail) { case GL_KEEP: case GL_ZERO: case GL_REPLACE: case GL_INCR: case GL_DECR: case GL_INVERT: break; case GL_INCR_WRAP_EXT: case GL_DECR_WRAP_EXT: if (ctx->Extensions.EXT_stencil_wrap) { break; } /* FALL-THROUGH */ default: _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(fail)"); return; } switch (zfail) { case GL_KEEP: case GL_ZERO: case GL_REPLACE: case GL_INCR: case GL_DECR: case GL_INVERT: break; case GL_INCR_WRAP_EXT: case GL_DECR_WRAP_EXT: if (ctx->Extensions.EXT_stencil_wrap) { break; } /* FALL-THROUGH */ default: _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)"); return; } switch (zpass) { case GL_KEEP: case GL_ZERO: case GL_REPLACE: case GL_INCR: case GL_DECR: case GL_INVERT: break; case GL_INCR_WRAP_EXT: case GL_DECR_WRAP_EXT: if (ctx->Extensions.EXT_stencil_wrap) { break; } /* FALL-THROUGH */ default: _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)"); return; } FLUSH_VERTICES(ctx, _NEW_STENCIL); if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { ctx->Stencil.FailFunc[0] = fail; ctx->Stencil.ZFailFunc[0] = zfail; ctx->Stencil.ZPassFunc[0] = zpass; } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { ctx->Stencil.FailFunc[1] = fail; ctx->Stencil.ZFailFunc[1] = zfail; ctx->Stencil.ZPassFunc[1] = zpass; } if (ctx->Driver.StencilOpSeparate) { ctx->Driver.StencilOpSeparate(ctx, face, fail, zfail, zpass); }}/* OpenGL 2.0 */void GLAPIENTRY_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask){ GET_CURRENT_CONTEXT(ctx); const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; ASSERT_OUTSIDE_BEGIN_END(ctx); if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(face)"); return; } switch (func) { case GL_NEVER: case GL_LESS: case GL_LEQUAL: case GL_GREATER: case GL_GEQUAL: case GL_EQUAL: case GL_NOTEQUAL: case GL_ALWAYS: break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)"); return; } ref = CLAMP(ref, 0, stencilMax); FLUSH_VERTICES(ctx, _NEW_STENCIL); if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { ctx->Stencil.Function[0] = func; ctx->Stencil.Ref[0] = ref; ctx->Stencil.ValueMask[0] = mask; } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { ctx->Stencil.Function[1] = func; ctx->Stencil.Ref[1] = ref; ctx->Stencil.ValueMask[1] = mask; } if (ctx->Driver.StencilFuncSeparate) { ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask); }}/* OpenGL 2.0 */void GLAPIENTRY_mesa_StencilMaskSeparate(GLenum face, GLuint mask){ GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { _mesa_error(ctx, GL_INVALID_ENUM, "glStencilaMaskSeparate(face)"); return; } FLUSH_VERTICES(ctx, _NEW_STENCIL); if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { ctx->Stencil.WriteMask[0] = mask; } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { ctx->Stencil.WriteMask[1] = mask; } if (ctx->Driver.StencilMaskSeparate) { ctx->Driver.StencilMaskSeparate(ctx, face, mask); }}/** * Update derived stencil state. */void_mesa_update_stencil(GLcontext *ctx){ if (ctx->Extensions.EXT_stencil_two_side) { ctx->Stencil._TestTwoSide = ctx->Stencil.TestTwoSide; } else { ctx->Stencil._TestTwoSide = (ctx->Stencil.Function[0] != ctx->Stencil.Function[1] || ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[1] || ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[1] || ctx->Stencil.ZFailFunc[0] != ctx->Stencil.ZFailFunc[1] || ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] || ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[1] || ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[1]); }}/** * Initialize the context stipple state. * * \param ctx GL context. * * Initializes __GLcontextRec::Stencil attribute group. */void_mesa_init_stencil(GLcontext *ctx){ ctx->Stencil.Enabled = GL_FALSE; ctx->Stencil.TestTwoSide = GL_FALSE; ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 1 = GL_BACK */ ctx->Stencil.Function[0] = GL_ALWAYS; ctx->Stencil.Function[1] = GL_ALWAYS; ctx->Stencil.FailFunc[0] = GL_KEEP; ctx->Stencil.FailFunc[1] = GL_KEEP; ctx->Stencil.ZPassFunc[0] = GL_KEEP; ctx->Stencil.ZPassFunc[1] = GL_KEEP; ctx->Stencil.ZFailFunc[0] = GL_KEEP; ctx->Stencil.ZFailFunc[1] = GL_KEEP; ctx->Stencil.Ref[0] = 0; ctx->Stencil.Ref[1] = 0; ctx->Stencil.ValueMask[0] = ~0U; ctx->Stencil.ValueMask[1] = ~0U; ctx->Stencil.WriteMask[0] = ~0U; ctx->Stencil.WriteMask[1] = ~0U; ctx->Stencil.Clear = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -