stencil.c

来自「Mesa is an open-source implementation of」· C语言 代码 · 共 561 行 · 第 1/2 页

C
561
字号
      if (ctx->Driver.StencilMaskSeparate) {         ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT_AND_BACK, mask);      }   }}/** * Set the stencil test actions. * * \param fail action to take when stencil test fails. * \param zfail action to take when stencil test passes, but depth test fails. * \param zpass action to take when stencil test passes and the depth test * passes (or depth testing is not enabled). *  * \sa glStencilOp(). *  * Verifies the parameters and updates the respective fields in * __GLcontextRec::Stencil. On change flushes the vertices and notifies the * driver via the dd_function_table::StencilOp callback. */void GLAPIENTRY_mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass){   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END(ctx);   if (!validate_stencil_op(ctx, fail)) {      _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(sfail)");      return;   }   if (!validate_stencil_op(ctx, zfail)) {      _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zfail)");      return;   }   if (!validate_stencil_op(ctx, zpass)) {      _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zpass)");      return;   }   if (ctx->Extensions.EXT_stencil_two_side) {      /* only set active face state */      const GLint face = ctx->Stencil.ActiveFace;      if (ctx->Stencil.ZFailFunc[face] == zfail &&          ctx->Stencil.ZPassFunc[face] == zpass &&          ctx->Stencil.FailFunc[face] == fail)         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 sfail, GLenum zfail, GLenum zpass){   GLboolean set = GL_FALSE;   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END(ctx);   if (!validate_stencil_op(ctx, sfail)) {      _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(sfail)");      return;   }   if (!validate_stencil_op(ctx, zfail)) {      _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)");      return;   }   if (!validate_stencil_op(ctx, zpass)) {      _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)");      return;   }   if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {      _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(face)");      return;   }   if (face != GL_BACK) {      /* set front */      if (ctx->Stencil.ZFailFunc[0] != zfail ||          ctx->Stencil.ZPassFunc[0] != zpass ||          ctx->Stencil.FailFunc[0] != sfail){         FLUSH_VERTICES(ctx, _NEW_STENCIL);         ctx->Stencil.ZFailFunc[0] = zfail;         ctx->Stencil.ZPassFunc[0] = zpass;         ctx->Stencil.FailFunc[0] = sfail;         set = GL_TRUE;      }   }   if (face != GL_FRONT) {      /* set back */      if (ctx->Stencil.ZFailFunc[1] != zfail ||          ctx->Stencil.ZPassFunc[1] != zpass ||          ctx->Stencil.FailFunc[1] != sfail) {         FLUSH_VERTICES(ctx, _NEW_STENCIL);         ctx->Stencil.ZFailFunc[1] = zfail;         ctx->Stencil.ZPassFunc[1] = zpass;         ctx->Stencil.FailFunc[1] = sfail;         set = GL_TRUE;      }   }   if (set && ctx->Driver.StencilOpSeparate) {      ctx->Driver.StencilOpSeparate(ctx, face, sfail, 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;   }   if (!validate_stencil_func(ctx, func)) {      _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)");      return;   }   ref = CLAMP(ref, 0, stencilMax);   FLUSH_VERTICES(ctx, _NEW_STENCIL);   if (face != GL_BACK) {      /* set front */      ctx->Stencil.Function[0] = func;      ctx->Stencil.Ref[0] = ref;      ctx->Stencil.ValueMask[0] = mask;   }   if (face != GL_FRONT) {      /* set 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_BACK) {      ctx->Stencil.WriteMask[0] = mask;   }   if (face != GL_FRONT) {      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 + =
减小字号Ctrl + -
显示快捷键?