STENCIL_OP StencilOpFromString(const char* str) { if (!str) return STENCIL_OP_KEEP; for (int i = 1; i <= 8; ++i) { if (_stricmp(str, STR_STENCIL_OP[i - 1]) == 0) return STENCIL_OP(i); } Logger::Log(FB_ERROR_LOG_ARG, FormatString("%s is not valid StencilOp", str).c_str()); return STENCIL_OP_KEEP; }
/** * Apply the given stencil operator to the array of stencil values. * Don't touch stencil[i] if mask[i] is zero. * @param n number of stencil values * @param oper the stencil buffer operator * @param face 0 or 1 for front or back face operation * @param stencil array of stencil values (in/out) * @param mask array [n] of flag: 1=apply operator, 0=don't apply operator * @param stride stride between stencil values */ static void apply_stencil_op(const struct gl_context *ctx, GLenum oper, GLuint face, GLuint n, GLubyte stencil[], const GLubyte mask[], GLint stride) { const GLubyte ref = ctx->Stencil.Ref[face]; const GLubyte wrtmask = ctx->Stencil.WriteMask[face]; const GLubyte invmask = (GLubyte) (~wrtmask); GLuint i, j; switch (oper) { case GL_KEEP: /* do nothing */ break; case GL_ZERO: /* replace stencil buf values with zero */ STENCIL_OP(0); break; case GL_REPLACE: /* replace stencil buf values with ref value */ STENCIL_OP(ref); break; case GL_INCR: /* increment stencil buf values, with clamping */ STENCIL_OP(clamp(s + 1)); break; case GL_DECR: /* increment stencil buf values, with clamping */ STENCIL_OP(clamp(s - 1)); break; case GL_INCR_WRAP_EXT: /* increment stencil buf values, without clamping */ STENCIL_OP(s + 1); break; case GL_DECR_WRAP_EXT: /* increment stencil buf values, without clamping */ STENCIL_OP(s - 1); break; case GL_INVERT: /* replace stencil buf values with inverted value */ STENCIL_OP(~s); break; default: _mesa_problem(ctx, "Bad stencil op in apply_stencil_op"); } }