GL_EXT_stencil_two_side extension, not 100% complete yet.
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 6 Sep 2002 02:56:08 +0000 (02:56 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 6 Sep 2002 02:56:08 +0000 (02:56 +0000)
14 files changed:
src/mesa/main/attrib.c
src/mesa/main/context.c
src/mesa/main/dd.h
src/mesa/main/dlist.c
src/mesa/main/enable.c
src/mesa/main/extensions.c
src/mesa/main/get.c
src/mesa/main/mtypes.h
src/mesa/main/state.c
src/mesa/main/stencil.c
src/mesa/main/stencil.h
src/mesa/swrast/s_span.c
src/mesa/swrast/s_stencil.c
src/mesa/swrast/s_stencil.h

index a7448ee32a1895a8cdc9999ef218d20954c87eec..2ebaaf734148c8f270d21a9b07cd60f860a9a3cb 100644 (file)
@@ -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:
index 7fa32c601c0871bb44cb209988ab9996fd5e3022..4a0b4ed23d664592b77cbe575ebfddb564b0fcd7 100644 (file)
@@ -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 */
index 81ae9e4a1255dce9641f51aaed3ef1ff8e7d0710..fcf0ceeb0de9a1e0b6e27f3518a1eab78a224f6a 100644 (file)
@@ -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,
index deb4995ff14d8a703d7d28c21e5fd8fb57ccc58e..488e8a0040e2c3efdfcbdd5548babe5c6b9bf887 100644 (file)
@@ -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;
index 140358b463a64140446719f3f28b4f1d7deb4ffe..0f51078c61896de2164685e9a407974eeca639ef 100644 (file)
@@ -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;
index dce0be620c1c41c9545281cf77f5adb7bc6f547d..24ab1ab244aedb724d2efd104837d11a4a83da69 100644 (file)
@@ -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",
index 2b92de7922941cae74ab373e8dab7b17f3b7b5a8..509fc8c2b3cd0df9c60d390c0d0ab7bd31e5a287 100644 (file)
@@ -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);
    }
index 6f33ae6658d7160823ef876971410420a1a3886a..99349968869f7e34e28d80f4dab5fc0667bfc61c 100644 (file)
@@ -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;
index 500ba2640ffa3b361a9b473c643ef01795eb054e..ced61a4e497c17c0b871f339ac7753177450ba0b 100644 (file)
@@ -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;
index 55a08388697c4176361700f4913aa5f08f7d071b..99f213c8541adb5493a15a33941c5fb93038bb5a 100644 (file)
@@ -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 );
+   }
+}
+
index 6d659d3eb85dc4b76a8c57181e90d0d12cbf56e2..41b9a72464e52ba60c252af5674e84a6f5815935 100644 (file)
@@ -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
index 67636569afc35b09765e50b3401fe6433a22df6c..74fccc55c7219227eb492bd3c564c0b39234189e 100644 (file)
@@ -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;
          }
index 775868cb677696475072e2b04ffa63dbc900ad1a..4ec64ee8481f912dc8612668de5da58e6954d4a2 100644 (file)
@@ -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;i<n;i++) {
@@ -266,10 +269,10 @@ do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[],
         allfail = GL_TRUE;
         break;
       case GL_LESS:
-        r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+        r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
         for (i=0;i<n;i++) {
            if (mask[i]) {
-              s = (GLstencil) (stencil[i] & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
-              s = (GLstencil) (stencil[i] & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
-              s = (GLstencil) (stencil[i] & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
-              s = (GLstencil) (stencil[i] & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
-              s = (GLstencil) (stencil[i] & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
-              s = (GLstencil) (stencil[i] & ctx->Stencil.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;i<n;i++) {
@@ -733,11 +739,11 @@ stencil_test_pixels( GLcontext *ctx, GLuint n,
         allfail = GL_TRUE;
         break;
       case GL_LESS:
-        r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask);
+        r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
         for (i=0;i<n;i++) {
            if (mask[i]) {
                GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
-              s = (GLstencil) (*sptr & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
                GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
-              s = (GLstencil) (*sptr & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
                GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
-              s = (GLstencil) (*sptr & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
                GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
-              s = (GLstencil) (*sptr & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
                GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
-              s = (GLstencil) (*sptr & ctx->Stencil.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;i<n;i++) {
            if (mask[i]) {
                GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
-              s = (GLstencil) (*sptr & ctx->Stencil.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;
index d15b5d2d4a1175f23450e52b2c778c15feafe080..ec76edaf78b40cddd31e97e4ce056cde7d757d4a 100644 (file)
@@ -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);