From 5f60a0b50ada1865d4fc6a724366e8ea0cc9a72f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 6 Sep 2002 02:56:08 +0000 Subject: [PATCH] GL_EXT_stencil_two_side extension, not 100% complete yet. --- src/mesa/main/attrib.c | 15 ++-- src/mesa/main/context.c | 25 ++++-- src/mesa/main/dd.h | 11 ++- src/mesa/main/dlist.c | 28 ++++++- src/mesa/main/enable.c | 17 +++- src/mesa/main/extensions.c | 4 +- src/mesa/main/get.c | 98 +++++++++++++++------- src/mesa/main/mtypes.h | 42 +++++++--- src/mesa/main/state.c | 7 +- src/mesa/main/stencil.c | 60 +++++++++----- src/mesa/main/stencil.h | 9 ++- src/mesa/swrast/s_span.c | 22 +++-- src/mesa/swrast/s_stencil.c | 156 +++++++++++++++++++----------------- src/mesa/swrast/s_stencil.h | 4 +- 14 files changed, 332 insertions(+), 166 deletions(-) diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index a7448ee32a1..2ebaaf73414 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1,4 +1,4 @@ -/* $Id: attrib.c,v 1.70 2002/09/03 18:03:45 brianp Exp $ */ +/* $Id: attrib.c,v 1.71 2002/09/06 02:56:08 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -513,6 +513,7 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable) GL_POLYGON_STIPPLE); TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST); TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); + /* XXX two-sided stencil */ TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled, GL_MULTISAMPLE_ARB); TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, @@ -1032,15 +1033,17 @@ _mesa_PopAttrib(void) break; case GL_STENCIL_BUFFER_BIT: { + const GLint face = 0; /* XXX stencil two side */ const struct gl_stencil_attrib *stencil; stencil = (const struct gl_stencil_attrib *) attr->data; _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); _mesa_ClearStencil(stencil->Clear); - _mesa_StencilFunc(stencil->Function, stencil->Ref, - stencil->ValueMask); - _mesa_StencilMask(stencil->WriteMask); - _mesa_StencilOp(stencil->FailFunc, stencil->ZFailFunc, - stencil->ZPassFunc); + _mesa_StencilFunc(stencil->Function[face], stencil->Ref[face], + stencil->ValueMask[face]); + _mesa_StencilMask(stencil->WriteMask[face]); + _mesa_StencilOp(stencil->FailFunc[face], + stencil->ZFailFunc[face], + stencil->ZPassFunc[face]); } break; case GL_TRANSFORM_BIT: diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 7fa32c601c0..4a0b4ed23d6 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,4 +1,4 @@ -/* $Id: context.c,v 1.175 2002/07/09 01:22:50 brianp Exp $ */ +/* $Id: context.c,v 1.176 2002/09/06 02:56:08 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1288,14 +1288,23 @@ init_attrib_groups( GLcontext *ctx ) /* Stencil group */ ctx->Stencil.Enabled = GL_FALSE; - ctx->Stencil.Function = GL_ALWAYS; - ctx->Stencil.FailFunc = GL_KEEP; - ctx->Stencil.ZPassFunc = GL_KEEP; - ctx->Stencil.ZFailFunc = GL_KEEP; - ctx->Stencil.Ref = 0; - ctx->Stencil.ValueMask = STENCIL_MAX; + ctx->Stencil.TestTwoSide = GL_FALSE; + ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 1 = GL_BACK */ + ctx->Stencil.Function[0] = GL_ALWAYS; + ctx->Stencil.Function[1] = GL_ALWAYS; + ctx->Stencil.FailFunc[0] = GL_KEEP; + ctx->Stencil.FailFunc[1] = GL_KEEP; + ctx->Stencil.ZPassFunc[0] = GL_KEEP; + ctx->Stencil.ZPassFunc[1] = GL_KEEP; + ctx->Stencil.ZFailFunc[0] = GL_KEEP; + ctx->Stencil.ZFailFunc[1] = GL_KEEP; + ctx->Stencil.Ref[0] = 0; + ctx->Stencil.Ref[1] = 0; + ctx->Stencil.ValueMask[0] = STENCIL_MAX; + ctx->Stencil.ValueMask[1] = STENCIL_MAX; + ctx->Stencil.WriteMask[0] = STENCIL_MAX; + ctx->Stencil.WriteMask[1] = STENCIL_MAX; ctx->Stencil.Clear = 0; - ctx->Stencil.WriteMask = STENCIL_MAX; /* Texture group */ ctx->Texture.CurrentUnit = 0; /* multitexture */ diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 81ae9e4a125..fcf0ceeb0de 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.70 2002/07/09 01:22:50 brianp Exp $ */ +/* $Id: dd.h,v 1.71 2002/09/06 02:56:08 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -458,14 +458,22 @@ struct dd_function_table { *** They're ALSO called by the gl_PopAttrib() function!!! *** May add more functions like these to the device driver in the future. ***/ +#if 1 void (*AlphaFunc)(GLcontext *ctx, GLenum func, GLchan ref); +#else + void (*AlphaFunc)(GLcontext *ctx, GLenum func, GLfloat ref); +#endif void (*BlendColor)(GLcontext *ctx, const GLfloat color[4]); void (*BlendEquation)(GLcontext *ctx, GLenum mode); void (*BlendFunc)(GLcontext *ctx, GLenum sfactor, GLenum dfactor); void (*BlendFuncSeparate)(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA); +#if 1 void (*ClearColor)(GLcontext *ctx, const GLchan color[4]); +#else + void (*ClearColor)(GLcontext *ctx, const GLfloat color[4]); +#endif void (*ClearDepth)(GLcontext *ctx, GLclampd d); void (*ClearIndex)(GLcontext *ctx, GLuint index); void (*ClearStencil)(GLcontext *ctx, GLint s); @@ -500,6 +508,7 @@ struct dd_function_table { void (*StencilFunc)(GLcontext *ctx, GLenum func, GLint ref, GLuint mask); void (*StencilMask)(GLcontext *ctx, GLuint mask); void (*StencilOp)(GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass); + void (*ActiveStencilFace)(GLcontext *ctx, GLuint face); void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, const GLfloat *params); void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index deb4995ff14..488e8a0040e 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -1,4 +1,4 @@ -/* $Id: dlist.c,v 1.93 2002/08/17 00:26:29 brianp Exp $ */ +/* $Id: dlist.c,v 1.94 2002/09/06 02:56:08 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -253,6 +253,8 @@ typedef enum { OPCODE_PROGRAM_PARAMETER4F_NV, OPCODE_PROGRAM_PARAMETERS4FV_NV, OPCODE_TRACK_MATRIX_NV, + /* GL_EXT_stencil_two_face */ + OPCODE_ACTIVE_STENCIL_FACE_EXT, /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, @@ -648,6 +650,8 @@ void _mesa_init_lists( void ) InstSize[OPCODE_PROGRAM_PARAMETER4F_NV] = 7; InstSize[OPCODE_PROGRAM_PARAMETERS4FV_NV] = 4; InstSize[OPCODE_TRACK_MATRIX_NV] = 5; + /* GL_EXT_stencil_two_side */ + InstSize[OPCODE_ACTIVE_STENCIL_FACE_EXT] = 2; } init_flag = 1; } @@ -4094,6 +4098,23 @@ save_TrackMatrixNV(GLenum target, GLuint address, } +/* GL_EXT_stencil_two_face */ +static void save_ActiveStencilFaceEXT( GLenum face ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ACTIVE_STENCIL_FACE_EXT, 1 ); + if (n) { + n[1].e = face; + } + if (ctx->ExecuteFlag) { +#if 0 + (*ctx->Exec->ActiveStencilFaceEXT)( face ); +#endif + } +} + /* KW: Compile commands @@ -6182,6 +6203,11 @@ _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize ) table->PointParameteriNV = save_PointParameteriNV; table->PointParameterivNV = save_PointParameterivNV; + /* 268. GL_EXT_stencil_two_side */ +#if 0 + table->ActiveStencilFaceEXT = save_ActiveStencilFaceEXT; +#endif + /* ARB 1. GL_ARB_multitexture */ table->ActiveTextureARB = save_ActiveTextureARB; table->ClientActiveTextureARB = exec_ClientActiveTextureARB; diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 140358b463a..0f51078c618 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -1,4 +1,4 @@ -/* $Id: enable.c,v 1.68 2002/06/29 19:48:15 brianp Exp $ */ +/* $Id: enable.c,v 1.69 2002/09/06 02:56:08 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -875,6 +875,7 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) /* GL_NV_texture_rectangle */ case GL_TEXTURE_RECTANGLE_NV: + CHECK_EXTENSION(NV_texture_rectangle, cap); { const GLuint curr = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr]; @@ -889,6 +890,15 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) } break; + /* GL_EXT_stencil_two_side */ + case GL_STENCIL_TEST_TWO_SIDE_EXT: + CHECK_EXTENSION(EXT_stencil_two_side, cap); + if (ctx->Stencil.TestTwoSide == state) + return; + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.TestTwoSide = state; + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "%s(0x%x)", state ? "glEnable" : "glDisable", cap); @@ -1263,6 +1273,11 @@ _mesa_IsEnabled( GLenum cap ) return (texUnit->Enabled & TEXTURE_RECT_BIT) ? GL_TRUE : GL_FALSE; } + /* GL_EXT_stencil_two_side */ + case GL_STENCIL_TEST_TWO_SIDE_EXT: + CHECK_EXTENSION(EXT_stencil_two_side); + return ctx->Stencil.TestTwoSide; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap); return GL_FALSE; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index dce0be620c1..24ab1ab244a 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -1,4 +1,4 @@ -/* $Id: extensions.c,v 1.77 2002/09/05 21:16:30 brianp Exp $ */ +/* $Id: extensions.c,v 1.78 2002/09/06 02:56:08 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -95,6 +95,7 @@ static struct { { OFF, "GL_EXT_shadow_funcs", F(EXT_shadow_funcs) }, { OFF, "GL_EXT_shared_texture_palette", F(EXT_shared_texture_palette) }, { OFF, "GL_EXT_stencil_wrap", F(EXT_stencil_wrap) }, + { OFF, "GL_EXT_stencil_two_side", F(EXT_stencil_two_side) }, { ON, "GL_EXT_texture3D", F(EXT_texture3D) }, { OFF, "GL_EXT_texture_compression_s3tc", F(EXT_texture_compression_s3tc) }, { OFF, "GL_EXT_texture_edge_clamp", F(SGIS_texture_edge_clamp) }, @@ -170,6 +171,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) "GL_EXT_secondary_color", "GL_EXT_shared_texture_palette", "GL_EXT_stencil_wrap", + "GL_EXT_stencil_two_side", "GL_EXT_texture_edge_clamp", "GL_EXT_texture_env_add", "GL_EXT_texture_env_combine", diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 2b92de79229..509fc8c2b3c 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1,4 +1,4 @@ -/* $Id: get.c,v 1.88 2002/09/05 21:14:36 brianp Exp $ */ +/* $Id: get.c,v 1.89 2002/09/06 02:56:08 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -802,28 +802,28 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) *params = INT_TO_BOOL(ctx->Stencil.Clear); break; case GL_STENCIL_FAIL: - *params = ENUM_TO_BOOL(ctx->Stencil.FailFunc); + *params = ENUM_TO_BOOL(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_FUNC: - *params = ENUM_TO_BOOL(ctx->Stencil.Function); + *params = ENUM_TO_BOOL(ctx->Stencil.Function[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_PASS_DEPTH_FAIL: - *params = ENUM_TO_BOOL(ctx->Stencil.ZFailFunc); + *params = ENUM_TO_BOOL(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_PASS_DEPTH_PASS: - *params = ENUM_TO_BOOL(ctx->Stencil.ZPassFunc); + *params = ENUM_TO_BOOL(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_REF: - *params = INT_TO_BOOL(ctx->Stencil.Ref); + *params = INT_TO_BOOL(ctx->Stencil.Ref[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_TEST: *params = ctx->Stencil.Enabled; break; case GL_STENCIL_VALUE_MASK: - *params = INT_TO_BOOL(ctx->Stencil.ValueMask); + *params = INT_TO_BOOL(ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_WRITEMASK: - *params = INT_TO_BOOL(ctx->Stencil.WriteMask); + *params = INT_TO_BOOL(ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]); break; case GL_STEREO: *params = ctx->Visual.stereoMode; @@ -1466,6 +1466,16 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) *params = INT_TO_BOOL(ctx->Const.MaxTextureRectSize); break; + /* GL_EXT_stencil_two_side */ + case GL_STENCIL_TEST_TWO_SIDE_EXT: + CHECK_EXTENSION_B(EXT_stencil_two_side, pname); + *params = ctx->Stencil.TestTwoSide; + break; + case GL_ACTIVE_STENCIL_FACE_EXT: + CHECK_EXTENSION_B(EXT_stencil_two_side, pname); + *params = ENUM_TO_BOOL(ctx->Stencil.ActiveFace ? GL_FRONT : GL_BACK); + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname); } @@ -2159,28 +2169,28 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) *params = (GLdouble) ctx->Stencil.Clear; break; case GL_STENCIL_FAIL: - *params = ENUM_TO_DOUBLE(ctx->Stencil.FailFunc); + *params = ENUM_TO_DOUBLE(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_FUNC: - *params = ENUM_TO_DOUBLE(ctx->Stencil.Function); + *params = ENUM_TO_DOUBLE(ctx->Stencil.Function[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_PASS_DEPTH_FAIL: - *params = ENUM_TO_DOUBLE(ctx->Stencil.ZFailFunc); + *params = ENUM_TO_DOUBLE(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_PASS_DEPTH_PASS: - *params = ENUM_TO_DOUBLE(ctx->Stencil.ZPassFunc); + *params = ENUM_TO_DOUBLE(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_REF: - *params = (GLdouble) ctx->Stencil.Ref; + *params = (GLdouble) ctx->Stencil.Ref[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_TEST: *params = (GLdouble) ctx->Stencil.Enabled; break; case GL_STENCIL_VALUE_MASK: - *params = (GLdouble) ctx->Stencil.ValueMask; + *params = (GLdouble) ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_WRITEMASK: - *params = (GLdouble) ctx->Stencil.WriteMask; + *params = (GLdouble) ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]; break; case GL_STEREO: *params = (GLdouble) ctx->Visual.stereoMode; @@ -2820,6 +2830,16 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params ) *params = (GLdouble) ctx->Const.MaxTextureRectSize; break; + /* GL_EXT_stencil_two_side */ + case GL_STENCIL_TEST_TWO_SIDE_EXT: + CHECK_EXTENSION_D(EXT_stencil_two_side, pname); + *params = (GLdouble) ctx->Stencil.TestTwoSide; + break; + case GL_ACTIVE_STENCIL_FACE_EXT: + CHECK_EXTENSION_D(EXT_stencil_two_side, pname); + *params = (GLdouble) (ctx->Stencil.ActiveFace ? GL_FRONT : GL_BACK); + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev(pname=0x%x)", pname); } @@ -3515,28 +3535,28 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) *params = (GLfloat) ctx->Stencil.Clear; break; case GL_STENCIL_FAIL: - *params = ENUM_TO_FLOAT(ctx->Stencil.FailFunc); + *params = ENUM_TO_FLOAT(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_FUNC: - *params = ENUM_TO_FLOAT(ctx->Stencil.Function); + *params = ENUM_TO_FLOAT(ctx->Stencil.Function[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_PASS_DEPTH_FAIL: - *params = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc); + *params = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_PASS_DEPTH_PASS: - *params = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc); + *params = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]); break; case GL_STENCIL_REF: - *params = (GLfloat) ctx->Stencil.Ref; + *params = (GLfloat) ctx->Stencil.Ref[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_TEST: *params = (GLfloat) ctx->Stencil.Enabled; break; case GL_STENCIL_VALUE_MASK: - *params = (GLfloat) ctx->Stencil.ValueMask; + *params = (GLfloat) ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_WRITEMASK: - *params = (GLfloat) ctx->Stencil.WriteMask; + *params = (GLfloat) ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]; break; case GL_STEREO: *params = (GLfloat) ctx->Visual.stereoMode; @@ -4150,6 +4170,16 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) *params = (GLfloat) ctx->Const.MaxTextureRectSize; break; + /* GL_EXT_stencil_two_side */ + case GL_STENCIL_TEST_TWO_SIDE_EXT: + CHECK_EXTENSION_F(EXT_stencil_two_side, pname); + *params = (GLfloat) ctx->Stencil.TestTwoSide; + break; + case GL_ACTIVE_STENCIL_FACE_EXT: + CHECK_EXTENSION_F(EXT_stencil_two_side, pname); + *params = (GLfloat) (ctx->Stencil.ActiveFace ? GL_FRONT : GL_BACK); + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(0x%x)", pname); } @@ -4844,28 +4874,28 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) *params = (GLint) ctx->Stencil.Clear; break; case GL_STENCIL_FAIL: - *params = (GLint) ctx->Stencil.FailFunc; + *params = (GLint) ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_FUNC: - *params = (GLint) ctx->Stencil.Function; + *params = (GLint) ctx->Stencil.Function[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_PASS_DEPTH_FAIL: - *params = (GLint) ctx->Stencil.ZFailFunc; + *params = (GLint) ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_PASS_DEPTH_PASS: - *params = (GLint) ctx->Stencil.ZPassFunc; + *params = (GLint) ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_REF: - *params = (GLint) ctx->Stencil.Ref; + *params = (GLint) ctx->Stencil.Ref[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_TEST: *params = (GLint) ctx->Stencil.Enabled; break; case GL_STENCIL_VALUE_MASK: - *params = (GLint) ctx->Stencil.ValueMask; + *params = (GLint) ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]; break; case GL_STENCIL_WRITEMASK: - *params = (GLint) ctx->Stencil.WriteMask; + *params = (GLint) ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]; break; case GL_STEREO: *params = (GLint) ctx->Visual.stereoMode; @@ -5525,6 +5555,16 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) *params = (GLint) ctx->Const.MaxTextureRectSize; break; + /* GL_EXT_stencil_two_side */ + case GL_STENCIL_TEST_TWO_SIDE_EXT: + CHECK_EXTENSION_I(EXT_stencil_two_side, pname); + *params = (GLint) ctx->Stencil.TestTwoSide; + break; + case GL_ACTIVE_STENCIL_FACE_EXT: + CHECK_EXTENSION_I(EXT_stencil_two_side, pname); + *params = (GLint) (ctx->Stencil.ActiveFace ? GL_FRONT : GL_BACK); + break; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname); } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 6f33ae6658d..99349968869 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1,4 +1,4 @@ -/* $Id: mtypes.h,v 1.84 2002/07/09 01:22:50 brianp Exp $ */ +/* $Id: mtypes.h,v 1.85 2002/09/06 02:56:09 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -311,7 +311,11 @@ struct gl_accum_attrib { struct gl_colorbuffer_attrib { GLuint ClearIndex; /* Index to use for glClear */ +#if 1 GLchan ClearColor[4]; /* Color to use for glClear */ +#else + GLclampf ClearColor[4]; /* Color to use for glClear */ +#endif GLuint IndexMask; /* Color index write mask */ GLubyte ColorMask[4]; /* Each flag is 0xff or 0x0 */ @@ -323,7 +327,11 @@ struct gl_colorbuffer_attrib { /* alpha testing */ GLboolean AlphaEnabled; /* Alpha test enabled flag */ GLenum AlphaFunc; /* Alpha test function */ +#if 1 GLchan AlphaRef; /* Alpha ref value as GLchan */ +#else + GLclampf AlphaRef; +#endif /* blending */ GLboolean BlendEnabled; /* Blending enabled flag */ @@ -708,14 +716,16 @@ struct gl_scissor_attrib { struct gl_stencil_attrib { GLboolean Enabled; /* Enabled flag */ - GLenum Function; /* Stencil function */ - GLenum FailFunc; /* Fail function */ - GLenum ZPassFunc; /* Depth buffer pass function */ - GLenum ZFailFunc; /* Depth buffer fail function */ - GLstencil Ref; /* Reference value */ - GLstencil ValueMask; /* Value mask */ + GLboolean TestTwoSide; /* GL_EXT_stencil_two_side */ + GLubyte ActiveFace; /* GL_EXT_stencil_two_side (0 or 1) */ + GLenum Function[2]; /* Stencil function */ + GLenum FailFunc[2]; /* Fail function */ + GLenum ZPassFunc[2]; /* Depth buffer pass function */ + GLenum ZFailFunc[2]; /* Depth buffer fail function */ + GLstencil Ref[2]; /* Reference value */ + GLstencil ValueMask[2]; /* Value mask */ + GLstencil WriteMask[2]; /* Write mask */ GLstencil Clear; /* Clear value */ - GLstencil WriteMask; /* Write mask */ }; @@ -861,7 +871,10 @@ struct gl_texture_object { GLenum Target; /* GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ GLfloat Priority; /* in [0,1] */ GLfloat BorderValues[4]; /* unclamped */ +#if 1 + /* omit someday */ GLchan BorderColor[4]; /* clamped, as GLchan */ +#endif GLenum WrapS; /* Wrap modes are: GL_CLAMP, REPEAT */ GLenum WrapT; /* GL_CLAMP_TO_EDGE, and */ GLenum WrapR; /* GL_CLAMP_TO_BORDER_ARB */ @@ -874,7 +887,11 @@ struct gl_texture_object { GLfloat MaxAnisotropy; /* GL_EXT_texture_filter_anisotropic */ GLboolean CompareFlag; /* GL_SGIX_shadow */ GLenum CompareOperator; /* GL_SGIX_shadow */ +#if 1 GLchan ShadowAmbient; /* GL_SGIX/ARB_shadow_ambient */ +#else + GLfloat ShadowAmbient; +#endif GLenum CompareMode; /* GL_ARB_shadow */ GLenum CompareFunc; /* GL_ARB_shadow */ GLenum DepthMode; /* GL_ARB_depth_texture */ @@ -1310,11 +1327,17 @@ struct gl_frame_buffer { GLaccum *Accum; /* array [4*Width*Height] of GLaccum values */ /* Software alpha planes */ +#if 1 GLchan *FrontLeftAlpha; /* array [Width*Height] of GLubyte */ GLchan *BackLeftAlpha; /* array [Width*Height] of GLubyte */ GLchan *FrontRightAlpha; /* array [Width*Height] of GLubyte */ GLchan *BackRightAlpha; /* array [Width*Height] of GLubyte */ - +#else + GLvoid *FrontLeftAlpha; /* array [Width*Height] of GLubyte */ + GLvoid *BackLeftAlpha; /* array [Width*Height] of GLubyte */ + GLvoid *FrontRightAlpha; /* array [Width*Height] of GLubyte */ + GLvoid *BackRightAlpha; /* array [Width*Height] of GLubyte */ +#endif /* Drawing bounds: intersection of window size and scissor box */ GLint _Xmin, _Ymin; /* inclusive */ GLint _Xmax, _Ymax; /* exclusive */ @@ -1395,6 +1418,7 @@ struct gl_extensions { GLboolean EXT_secondary_color; GLboolean EXT_shared_texture_palette; GLboolean EXT_stencil_wrap; + GLboolean EXT_stencil_two_side; GLboolean EXT_texture3D; GLboolean EXT_texture_compression_s3tc; GLboolean EXT_texture_env_add; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 500ba2640ff..ced61a4e497 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1,4 +1,4 @@ -/* $Id: state.c,v 1.89 2002/07/09 01:22:50 brianp Exp $ */ +/* $Id: state.c,v 1.90 2002/09/06 02:56:09 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -492,6 +492,11 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize) exec->PointParameteriNV = _mesa_PointParameteriNV; exec->PointParameterivNV = _mesa_PointParameterivNV; + /* 268. GL_EXT_stencil_two_side */ +#if 0 + exec->ActiveStencilFaceEXT = _mesa_ActiveStencilFaceEXT; +#endif + /* ARB 1. GL_ARB_multitexture */ exec->ActiveTextureARB = _mesa_ActiveTextureARB; exec->ClientActiveTextureARB = _mesa_ClientActiveTextureARB; diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c index 55a08388697..99f213c8541 100644 --- a/src/mesa/main/stencil.c +++ b/src/mesa/main/stencil.c @@ -1,10 +1,10 @@ -/* $Id: stencil.c,v 1.27 2001/05/09 16:34:09 brianp Exp $ */ +/* $Id: stencil.c,v 1.28 2002/09/06 02:56:09 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 4.1 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -64,6 +64,7 @@ void _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) { GET_CURRENT_CONTEXT(ctx); + const GLint face = ctx->Stencil.ActiveFace; GLint maxref; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -85,18 +86,18 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) maxref = (1 << STENCIL_BITS) - 1; ref = (GLstencil) CLAMP( ref, 0, maxref ); - if (ctx->Stencil.Function == func && - ctx->Stencil.ValueMask == (GLstencil) mask && - ctx->Stencil.Ref == ref) + if (ctx->Stencil.Function[face] == func && + ctx->Stencil.ValueMask[face] == (GLstencil) mask && + ctx->Stencil.Ref[face] == ref) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.Function = func; - ctx->Stencil.Ref = ref; - ctx->Stencil.ValueMask = (GLstencil) mask; + ctx->Stencil.Function[face] = func; + ctx->Stencil.Ref[face] = ref; + ctx->Stencil.ValueMask[face] = (GLstencil) mask; if (ctx->Driver.StencilFunc) { - (*ctx->Driver.StencilFunc)( ctx, func, ctx->Stencil.Ref, mask ); + (*ctx->Driver.StencilFunc)( ctx, func, ref, mask ); } } @@ -106,13 +107,14 @@ void _mesa_StencilMask( GLuint mask ) { GET_CURRENT_CONTEXT(ctx); + const GLint face = ctx->Stencil.ActiveFace; ASSERT_OUTSIDE_BEGIN_END(ctx); - if (ctx->Stencil.WriteMask == (GLstencil) mask) - return; + if (ctx->Stencil.WriteMask[face] == (GLstencil) mask) + return; FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.WriteMask = (GLstencil) mask; + ctx->Stencil.WriteMask[face] = (GLstencil) mask; if (ctx->Driver.StencilMask) { (*ctx->Driver.StencilMask)( ctx, mask ); @@ -125,6 +127,7 @@ void _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) { GET_CURRENT_CONTEXT(ctx); + const GLint face = ctx->Stencil.ActiveFace; ASSERT_OUTSIDE_BEGIN_END(ctx); switch (fail) { @@ -182,17 +185,36 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) return; } - if (ctx->Stencil.ZFailFunc == zfail && - ctx->Stencil.ZPassFunc == zpass && - ctx->Stencil.FailFunc == fail) + if (ctx->Stencil.ZFailFunc[face] == zfail && + ctx->Stencil.ZPassFunc[face] == zpass && + ctx->Stencil.FailFunc[face] == fail) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.ZFailFunc = zfail; - ctx->Stencil.ZPassFunc = zpass; - ctx->Stencil.FailFunc = fail; + ctx->Stencil.ZFailFunc[face] = zfail; + ctx->Stencil.ZPassFunc[face] = zpass; + ctx->Stencil.FailFunc[face] = fail; if (ctx->Driver.StencilOp) { (*ctx->Driver.StencilOp)(ctx, fail, zfail, zpass); } } + + +/* GL_EXT_stencil_two_side */ +void +_mesa_ActiveStencilFaceEXT(GLenum face) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (face == GL_FRONT || face == GL_BACK) { + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 1; + } + + if (ctx->Driver.ActiveStencilFace) { + (*ctx->Driver.ActiveStencilFace)( ctx, (GLuint) ctx->Stencil.ActiveFace ); + } +} + diff --git a/src/mesa/main/stencil.h b/src/mesa/main/stencil.h index 6d659d3eb85..41b9a72464e 100644 --- a/src/mesa/main/stencil.h +++ b/src/mesa/main/stencil.h @@ -1,10 +1,10 @@ -/* $Id: stencil.h,v 1.9 2001/03/12 00:48:38 gareth Exp $ */ +/* $Id: stencil.h,v 1.10 2002/09/06 02:56:09 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 4.1 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -48,5 +48,8 @@ extern void _mesa_StencilOp( GLenum fail, GLenum zfail, GLenum zpass ); +extern void +_mesa_ActiveStencilFaceEXT(GLenum face); + #endif diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 67636569afc..74fccc55c72 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1,4 +1,4 @@ -/* $Id: s_span.c,v 1.46 2002/08/07 00:45:07 brianp Exp $ */ +/* $Id: s_span.c,v 1.47 2002/09/06 02:56:09 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -128,14 +128,9 @@ _mesa_span_default_texcoords( GLcontext *ctx, struct sw_span *span ) { GLuint i; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - span->tex[i][0] = ctx->Current.RasterTexCoords[i][0]; - span->tex[i][1] = ctx->Current.RasterTexCoords[i][1]; - span->tex[i][2] = ctx->Current.RasterTexCoords[i][2]; - span->tex[i][3] = ctx->Current.RasterTexCoords[i][3]; - span->texStepX[i][0] = 0.0; - span->texStepX[i][1] = 0.0; - span->texStepX[i][2] = 0.0; - span->texStepX[i][3] = 0.0; + COPY_4V(span->tex[i], ctx->Current.RasterTexCoords[i]); + ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); + ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); } span->interpMask |= SPAN_TEXTURE; } @@ -808,7 +803,8 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span) _mesa_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled) { - if (!_mesa_stencil_and_ztest_span(ctx, span)) { + const GLuint face = 0; /* XXX stencil two side */ + if (!_mesa_stencil_and_ztest_span(ctx, span, face)) { span->arrayMask = origArrayMask; return; } @@ -987,7 +983,8 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) _mesa_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled) { - if (!_mesa_stencil_and_ztest_span(ctx, span)) { + const GLuint face = 0; /* XXX stencil two side */ + if (!_mesa_stencil_and_ztest_span(ctx, span, face)) { span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; @@ -1217,7 +1214,8 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) _mesa_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled) { - if (!_mesa_stencil_and_ztest_span(ctx, span)) { + const GLuint face = 0; /* XXX stencil two side */ + if (!_mesa_stencil_and_ztest_span(ctx, span, face)) { span->arrayMask = origArrayMask; return; } diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c index 775868cb677..4ec64ee8481 100644 --- a/src/mesa/swrast/s_stencil.c +++ b/src/mesa/swrast/s_stencil.c @@ -1,4 +1,4 @@ -/* $Id: s_stencil.c,v 1.25 2002/08/07 00:45:07 brianp Exp $ */ +/* $Id: s_stencil.c,v 1.26 2002/09/06 02:56:09 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -65,17 +65,18 @@ ENDIF * Don't touch stencil[i] if mask[i] is zero. * Input: n - size of stencil array * oper - the stencil buffer operator + * face - 0 or 1 for front or back face operation * stencil - array of stencil values * mask - array [n] of flag: 1=apply operator, 0=don't apply operator * Output: stencil - modified values */ static void -apply_stencil_op( const GLcontext *ctx, GLenum oper, +apply_stencil_op( const GLcontext *ctx, GLenum oper, GLuint face, GLuint n, GLstencil stencil[], const GLubyte mask[] ) { - const GLstencil ref = ctx->Stencil.Ref; - const GLstencil wrtmask = ctx->Stencil.WriteMask; - const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask); + const GLstencil ref = ctx->Stencil.Ref[face]; + const GLstencil wrtmask = ctx->Stencil.WriteMask[face]; + const GLstencil invmask = (GLstencil) (~wrtmask); GLuint i; switch (oper) { @@ -223,7 +224,8 @@ apply_stencil_op( const GLcontext *ctx, GLenum oper, /** * Apply stencil test to an array of stencil values (before depth buffering). - * Input: n - number of pixels in the array + * Input: face - 0 or 1 for front or back-face polygons + * n - number of pixels in the array * stencil - array of [n] stencil values * mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel * Output: mask - pixels which fail the stencil test will have their @@ -232,13 +234,14 @@ apply_stencil_op( const GLcontext *ctx, GLenum oper, * Return: GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed. */ static GLboolean -do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], +do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], GLubyte mask[] ) { GLubyte fail[MAX_WIDTH]; GLboolean allfail = GL_FALSE; GLuint i; GLstencil r, s; + const GLuint valueMask = ctx->Stencil.ValueMask[face]; ASSERT(n <= MAX_WIDTH); @@ -251,7 +254,7 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], * the stencil fail operator is not to be applied * ENDIF */ - switch (ctx->Stencil.Function) { + switch (ctx->Stencil.Function[face]) { case GL_NEVER: /* never pass; always fail */ for (i=0;iStencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (stencil[i] & valueMask); if (r < s) { /* passed */ fail[i] = 0; @@ -285,10 +288,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], } break; case GL_LEQUAL: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (stencil[i] & valueMask); if (r <= s) { /* pass */ fail[i] = 0; @@ -304,10 +307,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], } break; case GL_GREATER: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (stencil[i] & valueMask); if (r > s) { /* passed */ fail[i] = 0; @@ -323,10 +326,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], } break; case GL_GEQUAL: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (stencil[i] & valueMask); if (r >= s) { /* passed */ fail[i] = 0; @@ -342,10 +345,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], } break; case GL_EQUAL: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (stencil[i] & valueMask); if (r == s) { /* passed */ fail[i] = 0; @@ -361,10 +364,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], } break; case GL_NOTEQUAL: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (stencil[i] & valueMask); if (r != s) { /* passed */ fail[i] = 0; @@ -390,8 +393,8 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], return 0; } - if (ctx->Stencil.FailFunc != GL_KEEP) { - apply_stencil_op( ctx, ctx->Stencil.FailFunc, n, stencil, fail ); + if (ctx->Stencil.FailFunc[face] != GL_KEEP) { + apply_stencil_op( ctx, ctx->Stencil.FailFunc[face], face, n, stencil, fail ); } return !allfail; @@ -412,7 +415,7 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], * */ static GLboolean -stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) +stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLstencil stencilRow[MAX_WIDTH]; @@ -447,7 +450,7 @@ stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) * Apply the stencil test to the fragments. * failMask[i] is 1 if the stencil test failed. */ - if (do_stencil_test( ctx, n, stencil, mask ) == GL_FALSE) { + if (do_stencil_test( ctx, face, n, stencil, mask ) == GL_FALSE) { /* all fragments failed the stencil test, we're done. */ span->writeAll = GL_FALSE; return GL_FALSE; @@ -461,7 +464,7 @@ stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) /* * No depth buffer, just apply zpass stencil function to active pixels. */ - apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, mask ); + apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face, n, stencil, mask ); } else { /* @@ -493,11 +496,13 @@ stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) } /* apply the pass and fail operations */ - if (ctx->Stencil.ZFailFunc != GL_KEEP) { - apply_stencil_op( ctx, ctx->Stencil.ZFailFunc, n, stencil, failmask ); + if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) { + apply_stencil_op( ctx, ctx->Stencil.ZFailFunc[face], face, + n, stencil, failmask ); } - if (ctx->Stencil.ZPassFunc != GL_KEEP) { - apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, passmask ); + if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) { + apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face, + n, stencil, passmask ); } } @@ -529,11 +534,11 @@ stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) static void apply_stencil_op_to_pixels( const GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], - GLenum oper, const GLubyte mask[] ) + GLenum oper, GLuint face, const GLubyte mask[] ) { - const GLstencil ref = ctx->Stencil.Ref; - const GLstencil wrtmask = ctx->Stencil.WriteMask; - const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask); + const GLstencil ref = ctx->Stencil.Ref[face]; + const GLstencil wrtmask = ctx->Stencil.WriteMask[face]; + const GLstencil invmask = (GLstencil) (~wrtmask); GLuint i; ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan); /* software stencil buffer only! */ @@ -695,13 +700,14 @@ apply_stencil_op_to_pixels( const GLcontext *ctx, * \return GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed. */ static GLboolean -stencil_test_pixels( GLcontext *ctx, GLuint n, +stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, const GLint x[], const GLint y[], GLubyte mask[] ) { GLubyte fail[MAX_WIDTH]; GLstencil r, s; GLuint i; GLboolean allfail = GL_FALSE; + const GLuint valueMask = ctx->Stencil.ValueMask[face]; /* software stencil buffer only! */ ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer); @@ -718,7 +724,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint n, * ENDIF */ - switch (ctx->Stencil.Function) { + switch (ctx->Stencil.Function[face]) { case GL_NEVER: /* always fail */ for (i=0;iStencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (*sptr & valueMask); if (r < s) { /* passed */ fail[i] = 0; @@ -753,11 +759,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n, } break; case GL_LEQUAL: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (*sptr & valueMask); if (r <= s) { /* pass */ fail[i] = 0; @@ -773,11 +779,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n, } break; case GL_GREATER: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (*sptr & valueMask); if (r > s) { /* passed */ fail[i] = 0; @@ -793,11 +799,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n, } break; case GL_GEQUAL: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (*sptr & valueMask); if (r >= s) { /* passed */ fail[i] = 0; @@ -813,11 +819,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n, } break; case GL_EQUAL: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (*sptr & valueMask); if (r == s) { /* passed */ fail[i] = 0; @@ -833,11 +839,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n, } break; case GL_NOTEQUAL: - r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;iStencil.ValueMask); + s = (GLstencil) (*sptr & valueMask); if (r != s) { /* passed */ fail[i] = 0; @@ -863,8 +869,9 @@ stencil_test_pixels( GLcontext *ctx, GLuint n, return 0; } - if (ctx->Stencil.FailFunc != GL_KEEP) { - apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc, fail ); + if (ctx->Stencil.FailFunc[face] != GL_KEEP) { + apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc[face], + face, fail ); } return !allfail; @@ -890,7 +897,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint n, * GL_TRUE - one or more fragments passed the testing */ static GLboolean -stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span ) +stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span, GLuint face ) { const GLuint n = span->end; const GLint *x = span->array->x; @@ -913,32 +920,33 @@ stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span ) MEMCPY(origMask, mask, n * sizeof(GLubyte)); - (void) do_stencil_test(ctx, n, stencil, mask); + (void) do_stencil_test(ctx, face, n, stencil, mask); if (ctx->Depth.Test == GL_FALSE) { - apply_stencil_op(ctx, ctx->Stencil.ZPassFunc, n, stencil, mask); + apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face, + n, stencil, mask); } else { _mesa_depth_test_span(ctx, span); - if (ctx->Stencil.ZFailFunc != GL_KEEP) { + if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) { GLubyte failmask[MAX_WIDTH]; GLuint i; for (i = 0; i < n; i++) { ASSERT(mask[i] == 0 || mask[i] == 1); failmask[i] = origMask[i] & (mask[i] ^ 1); } - apply_stencil_op(ctx, ctx->Stencil.ZFailFunc, + apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face, n, stencil, failmask); } - if (ctx->Stencil.ZPassFunc != GL_KEEP) { + if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) { GLubyte passmask[MAX_WIDTH]; GLuint i; for (i = 0; i < n; i++) { ASSERT(mask[i] == 0 || mask[i] == 1); passmask[i] = origMask[i] & mask[i]; } - apply_stencil_op(ctx, ctx->Stencil.ZPassFunc, + apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face, n, stencil, passmask); } } @@ -953,14 +961,14 @@ stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span ) ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer); - if (stencil_test_pixels(ctx, n, x, y, mask) == GL_FALSE) { + if (stencil_test_pixels(ctx, face, n, x, y, mask) == GL_FALSE) { /* all fragments failed the stencil test, we're done. */ return GL_FALSE; } if (ctx->Depth.Test==GL_FALSE) { apply_stencil_op_to_pixels(ctx, n, x, y, - ctx->Stencil.ZPassFunc, mask); + ctx->Stencil.ZPassFunc[face], face, mask); } else { GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH]; @@ -976,13 +984,15 @@ stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span ) failmask[i] = oldmask[i] & (mask[i] ^ 1); } - if (ctx->Stencil.ZFailFunc != GL_KEEP) { + if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) { apply_stencil_op_to_pixels(ctx, n, x, y, - ctx->Stencil.ZFailFunc, failmask); + ctx->Stencil.ZFailFunc[face], + face, failmask); } - if (ctx->Stencil.ZPassFunc != GL_KEEP) { + if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) { apply_stencil_op_to_pixels(ctx, n, x, y, - ctx->Stencil.ZPassFunc, passmask); + ctx->Stencil.ZPassFunc[face], + face, passmask); } } @@ -996,12 +1006,12 @@ stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span ) * GL_FALSE = all fragments failed. */ GLboolean -_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) +_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face) { if (span->arrayMask & SPAN_XY) - return stencil_and_ztest_pixels(ctx, span); + return stencil_and_ztest_pixels(ctx, span, face); else - return stencil_and_ztest_span(ctx, span); + return stencil_and_ztest_span(ctx, span, face); } @@ -1148,11 +1158,11 @@ clear_software_stencil_buffer( GLcontext *ctx ) if (ctx->Scissor.Enabled) { /* clear scissor region only */ const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - if (ctx->Stencil.WriteMask != STENCIL_MAX) { + if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { /* must apply mask to the clear */ GLint y; for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { - const GLstencil mask = ctx->Stencil.WriteMask; + const GLstencil mask = ctx->Stencil.WriteMask[0]; const GLstencil invMask = ~mask; const GLstencil clearVal = (ctx->Stencil.Clear & mask); GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y ); @@ -1179,11 +1189,11 @@ clear_software_stencil_buffer( GLcontext *ctx ) } else { /* clear whole stencil buffer */ - if (ctx->Stencil.WriteMask != STENCIL_MAX) { + if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { /* must apply mask to the clear */ const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; GLstencil *stencil = ctx->DrawBuffer->Stencil; - const GLstencil mask = ctx->Stencil.WriteMask; + const GLstencil mask = ctx->Stencil.WriteMask[0]; const GLstencil invMask = ~mask; const GLstencil clearVal = (ctx->Stencil.Clear & mask); GLuint i; @@ -1230,11 +1240,11 @@ clear_hardware_stencil_buffer( GLcontext *ctx ) /* clear scissor region only */ const GLint x = ctx->DrawBuffer->_Xmin; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - if (ctx->Stencil.WriteMask != STENCIL_MAX) { + if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { /* must apply mask to the clear */ GLint y; for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { - const GLstencil mask = ctx->Stencil.WriteMask; + const GLstencil mask = ctx->Stencil.WriteMask[0]; const GLstencil invMask = ~mask; const GLstencil clearVal = (ctx->Stencil.Clear & mask); GLstencil stencil[MAX_WIDTH]; @@ -1260,9 +1270,9 @@ clear_hardware_stencil_buffer( GLcontext *ctx ) } else { /* clear whole stencil buffer */ - if (ctx->Stencil.WriteMask != STENCIL_MAX) { + if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { /* must apply mask to the clear */ - const GLstencil mask = ctx->Stencil.WriteMask; + const GLstencil mask = ctx->Stencil.WriteMask[0]; const GLstencil invMask = ~mask; const GLstencil clearVal = (ctx->Stencil.Clear & mask); const GLint width = ctx->DrawBuffer->Width; diff --git a/src/mesa/swrast/s_stencil.h b/src/mesa/swrast/s_stencil.h index d15b5d2d4a1..ec76edaf78b 100644 --- a/src/mesa/swrast/s_stencil.h +++ b/src/mesa/swrast/s_stencil.h @@ -1,4 +1,4 @@ -/* $Id: s_stencil.h,v 1.7 2002/03/16 00:53:15 brianp Exp $ */ +/* $Id: s_stencil.h,v 1.8 2002/09/06 02:56:09 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -35,7 +35,7 @@ extern GLboolean -_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span); +_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face); -- 2.30.2