1 /* $Id: stencil.c,v 1.29 2002/10/24 23:57:21 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
39 _mesa_ClearStencil( GLint s
)
41 GET_CURRENT_CONTEXT(ctx
);
42 ASSERT_OUTSIDE_BEGIN_END(ctx
);
44 if (ctx
->Stencil
.Clear
== (GLstencil
) s
)
47 FLUSH_VERTICES(ctx
, _NEW_STENCIL
);
48 ctx
->Stencil
.Clear
= (GLstencil
) s
;
50 if (ctx
->Driver
.ClearStencil
) {
51 (*ctx
->Driver
.ClearStencil
)( ctx
, s
);
58 _mesa_StencilFunc( GLenum func
, GLint ref
, GLuint mask
)
60 GET_CURRENT_CONTEXT(ctx
);
61 const GLint face
= ctx
->Stencil
.ActiveFace
;
63 ASSERT_OUTSIDE_BEGIN_END(ctx
);
76 _mesa_error( ctx
, GL_INVALID_ENUM
, "glStencilFunc" );
80 maxref
= (1 << STENCIL_BITS
) - 1;
81 ref
= (GLstencil
) CLAMP( ref
, 0, maxref
);
83 if (ctx
->Stencil
.Function
[face
] == func
&&
84 ctx
->Stencil
.ValueMask
[face
] == (GLstencil
) mask
&&
85 ctx
->Stencil
.Ref
[face
] == ref
)
88 FLUSH_VERTICES(ctx
, _NEW_STENCIL
);
89 ctx
->Stencil
.Function
[face
] = func
;
90 ctx
->Stencil
.Ref
[face
] = ref
;
91 ctx
->Stencil
.ValueMask
[face
] = (GLstencil
) mask
;
93 if (ctx
->Driver
.StencilFunc
) {
94 (*ctx
->Driver
.StencilFunc
)( ctx
, func
, ref
, mask
);
101 _mesa_StencilMask( GLuint mask
)
103 GET_CURRENT_CONTEXT(ctx
);
104 const GLint face
= ctx
->Stencil
.ActiveFace
;
105 ASSERT_OUTSIDE_BEGIN_END(ctx
);
107 if (ctx
->Stencil
.WriteMask
[face
] == (GLstencil
) mask
)
110 FLUSH_VERTICES(ctx
, _NEW_STENCIL
);
111 ctx
->Stencil
.WriteMask
[face
] = (GLstencil
) mask
;
113 if (ctx
->Driver
.StencilMask
) {
114 (*ctx
->Driver
.StencilMask
)( ctx
, mask
);
121 _mesa_StencilOp(GLenum fail
, GLenum zfail
, GLenum zpass
)
123 GET_CURRENT_CONTEXT(ctx
);
124 const GLint face
= ctx
->Stencil
.ActiveFace
;
125 ASSERT_OUTSIDE_BEGIN_END(ctx
);
135 case GL_INCR_WRAP_EXT
:
136 case GL_DECR_WRAP_EXT
:
137 if (!ctx
->Extensions
.EXT_stencil_wrap
) {
142 _mesa_error(ctx
, GL_INVALID_ENUM
, "glStencilOp");
153 case GL_INCR_WRAP_EXT
:
154 case GL_DECR_WRAP_EXT
:
155 if (ctx
->Extensions
.EXT_stencil_wrap
) {
160 _mesa_error(ctx
, GL_INVALID_ENUM
, "glStencilOp");
171 case GL_INCR_WRAP_EXT
:
172 case GL_DECR_WRAP_EXT
:
173 if (ctx
->Extensions
.EXT_stencil_wrap
) {
178 _mesa_error(ctx
, GL_INVALID_ENUM
, "glStencilOp");
182 if (ctx
->Stencil
.ZFailFunc
[face
] == zfail
&&
183 ctx
->Stencil
.ZPassFunc
[face
] == zpass
&&
184 ctx
->Stencil
.FailFunc
[face
] == fail
)
187 FLUSH_VERTICES(ctx
, _NEW_STENCIL
);
188 ctx
->Stencil
.ZFailFunc
[face
] = zfail
;
189 ctx
->Stencil
.ZPassFunc
[face
] = zpass
;
190 ctx
->Stencil
.FailFunc
[face
] = fail
;
192 if (ctx
->Driver
.StencilOp
) {
193 (*ctx
->Driver
.StencilOp
)(ctx
, fail
, zfail
, zpass
);
198 /* GL_EXT_stencil_two_side */
200 _mesa_ActiveStencilFaceEXT(GLenum face
)
202 GET_CURRENT_CONTEXT(ctx
);
203 ASSERT_OUTSIDE_BEGIN_END(ctx
);
205 if (face
== GL_FRONT
|| face
== GL_BACK
) {
206 FLUSH_VERTICES(ctx
, _NEW_STENCIL
);
207 ctx
->Stencil
.ActiveFace
= (face
== GL_FRONT
) ? 0 : 1;
210 if (ctx
->Driver
.ActiveStencilFace
) {
211 (*ctx
->Driver
.ActiveStencilFace
)( ctx
, (GLuint
) ctx
->Stencil
.ActiveFace
);