Committing in .
[mesa.git] / src / mesa / main / stencil.c
1 /* $Id: stencil.c,v 1.23 2000/11/22 07:32:17 joukj 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
44 void
45 _mesa_ClearStencil( GLint s )
46 {
47 GET_CURRENT_CONTEXT(ctx);
48 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearStencil");
49 ctx->Stencil.Clear = (GLstencil) s;
50 ctx->NewState |= _NEW_STENCIL;
51
52 if (ctx->Driver.ClearStencil) {
53 (*ctx->Driver.ClearStencil)( ctx, s );
54 }
55 }
56
57
58
59 void
60 _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
61 {
62 GET_CURRENT_CONTEXT(ctx);
63 GLint maxref;
64
65 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glStencilFunc");
66
67 switch (func) {
68 case GL_NEVER:
69 case GL_LESS:
70 case GL_LEQUAL:
71 case GL_GREATER:
72 case GL_GEQUAL:
73 case GL_EQUAL:
74 case GL_NOTEQUAL:
75 case GL_ALWAYS:
76 ctx->Stencil.Function = func;
77 break;
78 default:
79 gl_error( ctx, GL_INVALID_ENUM, "glStencilFunc" );
80 return;
81 }
82
83 maxref = (1 << STENCIL_BITS) - 1;
84 ctx->Stencil.Ref = (GLstencil) CLAMP( ref, 0, maxref );
85 ctx->Stencil.ValueMask = (GLstencil) mask;
86 ctx->NewState |= _NEW_STENCIL;
87
88 if (ctx->Driver.StencilFunc) {
89 (*ctx->Driver.StencilFunc)( ctx, func, ctx->Stencil.Ref, mask );
90 }
91 }
92
93
94
95 void
96 _mesa_StencilMask( GLuint mask )
97 {
98 GET_CURRENT_CONTEXT(ctx);
99 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glStencilMask");
100 ctx->Stencil.WriteMask = (GLstencil) mask;
101 ctx->NewState |= _NEW_STENCIL;
102
103 if (ctx->Driver.StencilMask) {
104 (*ctx->Driver.StencilMask)( ctx, mask );
105 }
106 }
107
108
109
110 void
111 _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
112 {
113 GET_CURRENT_CONTEXT(ctx);
114 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glStencilOp");
115 switch (fail) {
116 case GL_KEEP:
117 case GL_ZERO:
118 case GL_REPLACE:
119 case GL_INCR:
120 case GL_DECR:
121 case GL_INVERT:
122 ctx->Stencil.FailFunc = fail;
123 break;
124 case GL_INCR_WRAP_EXT:
125 case GL_DECR_WRAP_EXT:
126 if (ctx->Extensions.EXT_stencil_wrap) {
127 ctx->Stencil.FailFunc = fail;
128 break;
129 }
130 /* FALL-THROUGH */
131 default:
132 gl_error(ctx, GL_INVALID_ENUM, "glStencilOp");
133 return;
134 }
135 switch (zfail) {
136 case GL_KEEP:
137 case GL_ZERO:
138 case GL_REPLACE:
139 case GL_INCR:
140 case GL_DECR:
141 case GL_INVERT:
142 ctx->Stencil.ZFailFunc = zfail;
143 break;
144 case GL_INCR_WRAP_EXT:
145 case GL_DECR_WRAP_EXT:
146 if (ctx->Extensions.EXT_stencil_wrap) {
147 ctx->Stencil.ZFailFunc = zfail;
148 break;
149 }
150 /* FALL-THROUGH */
151 default:
152 gl_error(ctx, GL_INVALID_ENUM, "glStencilOp");
153 return;
154 }
155 switch (zpass) {
156 case GL_KEEP:
157 case GL_ZERO:
158 case GL_REPLACE:
159 case GL_INCR:
160 case GL_DECR:
161 case GL_INVERT:
162 ctx->Stencil.ZPassFunc = zpass;
163 break;
164 case GL_INCR_WRAP_EXT:
165 case GL_DECR_WRAP_EXT:
166 if (ctx->Extensions.EXT_stencil_wrap) {
167 ctx->Stencil.ZPassFunc = zpass;
168 break;
169 }
170 /* FALL-THROUGH */
171 default:
172 gl_error(ctx, GL_INVALID_ENUM, "glStencilOp");
173 return;
174 }
175
176 ctx->NewState |= _NEW_STENCIL;
177
178 if (ctx->Driver.StencilOp) {
179 (*ctx->Driver.StencilOp)(ctx, fail, zfail, zpass);
180 }
181 }
182