/* OpenGL 2.0 */ void GLAPIENTRY _mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glStencilFuncSeparate()\n"); 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; } 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); } }
/** * Set the function and reference value for stencil testing. * * \param func test function. * \param ref reference value. * \param mask bitmask. * * \sa glStencilFunc(). * * Verifies the parameters and updates the respective values in * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the * driver via the dd_function_table::StencilFunc callback. */ void GLAPIENTRY _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) { GET_CURRENT_CONTEXT(ctx); const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; const GLint face = ctx->Stencil.ActiveFace; ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glStencilFunc()\n"); if (!validate_stencil_func(ctx, func)) { _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFunc(func)"); return; } ref = CLAMP( ref, 0, stencilMax ); if (face != 0) { if (ctx->Stencil.Function[face] == func && ctx->Stencil.ValueMask[face] == mask && ctx->Stencil.Ref[face] == ref) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); ctx->Stencil.Function[face] = func; ctx->Stencil.Ref[face] = ref; ctx->Stencil.ValueMask[face] = mask; /* Only propagate the change to the driver if EXT_stencil_two_side * is enabled. */ if (ctx->Driver.StencilFuncSeparate && ctx->Stencil.TestTwoSide) { ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, func, ref, mask); } } else { /* set both front and back state */ if (ctx->Stencil.Function[0] == func && ctx->Stencil.Function[1] == func && ctx->Stencil.ValueMask[0] == mask && ctx->Stencil.ValueMask[1] == mask && ctx->Stencil.Ref[0] == ref && ctx->Stencil.Ref[1] == ref) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); ctx->Stencil.Function[0] = ctx->Stencil.Function[1] = func; ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref; ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask; if (ctx->Driver.StencilFuncSeparate) { ctx->Driver.StencilFuncSeparate(ctx, ((ctx->Stencil.TestTwoSide) ? GL_FRONT : GL_FRONT_AND_BACK), func, ref, mask); } } }
/** * Set the function and reference value for stencil testing. * * \param frontfunc front test function. * \param backfunc back test function. * \param ref front and back reference value. * \param mask front and back bitmask. * * \sa glStencilFunc(). * * Verifies the parameters and updates the respective values in * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the * driver via the dd_function_table::StencilFunc callback. */ void GLAPIENTRY _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask ) { GET_CURRENT_CONTEXT(ctx); const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glStencilFuncSeparateATI()\n"); if (!validate_stencil_func(ctx, frontfunc)) { _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparateATI(frontfunc)"); return; } if (!validate_stencil_func(ctx, backfunc)) { _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparateATI(backfunc)"); return; } ref = CLAMP( ref, 0, stencilMax ); /* set both front and back state */ if (ctx->Stencil.Function[0] == frontfunc && ctx->Stencil.Function[1] == backfunc && ctx->Stencil.ValueMask[0] == mask && ctx->Stencil.ValueMask[1] == mask && ctx->Stencil.Ref[0] == ref && ctx->Stencil.Ref[1] == ref) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); ctx->Stencil.Function[0] = frontfunc; ctx->Stencil.Function[1] = backfunc; ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref; ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask; if (ctx->Driver.StencilFuncSeparate) { ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, frontfunc, ref, mask); ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, backfunc, ref, mask); } }
/* 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 (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glStencilFuncSeparate()\n"); 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); } }