stencil.c revision cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290
1/* $Id: stencil.c,v 1.24 2000/12/26 05:09:29 keithw Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28#ifdef PC_HEADER 29#include "all.h" 30#else 31#include "glheader.h" 32#include "context.h" 33#include "depth.h" 34#include "macros.h" 35#include "mem.h" 36#include "stencil.h" 37#include "mtypes.h" 38#include "enable.h" 39#endif 40 41 42 43 44void 45_mesa_ClearStencil( GLint s ) 46{ 47 GET_CURRENT_CONTEXT(ctx); 48 ASSERT_OUTSIDE_BEGIN_END(ctx); 49 50 if (ctx->Stencil.Clear == (GLstencil) s) 51 return; 52 53 FLUSH_VERTICES(ctx, _NEW_STENCIL); 54 ctx->Stencil.Clear = (GLstencil) s; 55 56 if (ctx->Driver.ClearStencil) { 57 (*ctx->Driver.ClearStencil)( ctx, s ); 58 } 59} 60 61 62 63void 64_mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) 65{ 66 GET_CURRENT_CONTEXT(ctx); 67 GLint maxref; 68 ASSERT_OUTSIDE_BEGIN_END(ctx); 69 70 switch (func) { 71 case GL_NEVER: 72 case GL_LESS: 73 case GL_LEQUAL: 74 case GL_GREATER: 75 case GL_GEQUAL: 76 case GL_EQUAL: 77 case GL_NOTEQUAL: 78 case GL_ALWAYS: 79 break; 80 default: 81 gl_error( ctx, GL_INVALID_ENUM, "glStencilFunc" ); 82 return; 83 } 84 85 maxref = (1 << STENCIL_BITS) - 1; 86 ref = (GLstencil) CLAMP( ref, 0, maxref ); 87 88 if (ctx->Stencil.Function == func && 89 ctx->Stencil.ValueMask == (GLstencil) mask && 90 ctx->Stencil.Ref == ref) 91 return; 92 93 FLUSH_VERTICES(ctx, _NEW_STENCIL); 94 ctx->Stencil.Function = func; 95 ctx->Stencil.Ref = ref; 96 ctx->Stencil.ValueMask = (GLstencil) mask; 97 98 if (ctx->Driver.StencilFunc) { 99 (*ctx->Driver.StencilFunc)( ctx, func, ctx->Stencil.Ref, mask ); 100 } 101} 102 103 104 105void 106_mesa_StencilMask( GLuint mask ) 107{ 108 GET_CURRENT_CONTEXT(ctx); 109 ASSERT_OUTSIDE_BEGIN_END(ctx); 110 111 if (ctx->Stencil.WriteMask == (GLstencil) mask) 112 return; 113 114 FLUSH_VERTICES(ctx, _NEW_STENCIL); 115 ctx->Stencil.WriteMask = (GLstencil) mask; 116 117 if (ctx->Driver.StencilMask) { 118 (*ctx->Driver.StencilMask)( ctx, mask ); 119 } 120} 121 122 123 124void 125_mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) 126{ 127 GET_CURRENT_CONTEXT(ctx); 128 ASSERT_OUTSIDE_BEGIN_END(ctx); 129 130 switch (fail) { 131 case GL_KEEP: 132 case GL_ZERO: 133 case GL_REPLACE: 134 case GL_INCR: 135 case GL_DECR: 136 case GL_INVERT: 137 ctx->Stencil.FailFunc = fail; 138 break; 139 case GL_INCR_WRAP_EXT: 140 case GL_DECR_WRAP_EXT: 141 if (!ctx->Extensions.EXT_stencil_wrap) { 142 break; 143 } 144 /* FALL-THROUGH */ 145 default: 146 gl_error(ctx, GL_INVALID_ENUM, "glStencilOp"); 147 return; 148 } 149 switch (zfail) { 150 case GL_KEEP: 151 case GL_ZERO: 152 case GL_REPLACE: 153 case GL_INCR: 154 case GL_DECR: 155 case GL_INVERT: 156 break; 157 case GL_INCR_WRAP_EXT: 158 case GL_DECR_WRAP_EXT: 159 if (ctx->Extensions.EXT_stencil_wrap) { 160 break; 161 } 162 /* FALL-THROUGH */ 163 default: 164 gl_error(ctx, GL_INVALID_ENUM, "glStencilOp"); 165 return; 166 } 167 switch (zpass) { 168 case GL_KEEP: 169 case GL_ZERO: 170 case GL_REPLACE: 171 case GL_INCR: 172 case GL_DECR: 173 case GL_INVERT: 174 break; 175 case GL_INCR_WRAP_EXT: 176 case GL_DECR_WRAP_EXT: 177 if (ctx->Extensions.EXT_stencil_wrap) { 178 break; 179 } 180 /* FALL-THROUGH */ 181 default: 182 gl_error(ctx, GL_INVALID_ENUM, "glStencilOp"); 183 return; 184 } 185 186 if (ctx->Stencil.ZFailFunc == zfail && 187 ctx->Stencil.ZPassFunc == zpass && 188 ctx->Stencil.FailFunc == fail) 189 return; 190 191 FLUSH_VERTICES(ctx, _NEW_STENCIL); 192 ctx->Stencil.ZFailFunc = zfail; 193 ctx->Stencil.ZPassFunc = zpass; 194 ctx->Stencil.FailFunc = fail; 195 196 if (ctx->Driver.StencilOp) { 197 (*ctx->Driver.StencilOp)(ctx, fail, zfail, zpass); 198 } 199} 200 201