fix broken two-sided stencil
authorBrian <brian.paul@tungstengraphics.com>
Fri, 30 Nov 2007 20:01:57 +0000 (13:01 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Fri, 30 Nov 2007 20:01:57 +0000 (13:01 -0700)
15 files changed:
src/mesa/main/context.c
src/mesa/main/mtypes.h
src/mesa/swrast/s_aalinetemp.h
src/mesa/swrast/s_aatritemp.h
src/mesa/swrast/s_context.c
src/mesa/swrast/s_context.h
src/mesa/swrast/s_fragprog.c
src/mesa/swrast/s_linetemp.h
src/mesa/swrast/s_points.c
src/mesa/swrast/s_triangle.c
src/mesa/swrast/s_tritemp.h
src/mesa/swrast/swrast.h
src/mesa/swrast_setup/ss_context.c
src/mesa/swrast_setup/ss_triangle.c
src/mesa/swrast_setup/ss_tritmp.h

index 08db12b1b67a1e430f68771a07059ec4f82e1e06..2ae0e1221d6fbcbe10f2fa241126ecc4fe0846e4 100644 (file)
@@ -992,7 +992,6 @@ init_attrib_groups(GLcontext *ctx)
    /* Miscellaneous */
    ctx->NewState = _NEW_ALL;
    ctx->ErrorValue = (GLenum) GL_NO_ERROR;
-   ctx->_Facing = 0;
 
    return GL_TRUE;
 }
index 1fbfeb7447bbd1ca83cf137da1a4cfeedac60151..94b709438892e1c96d20ae2695e3a92edba3125d 100644 (file)
@@ -3059,12 +3059,6 @@ struct __GLcontextRec
 
    struct gl_list_extensions ListExt; /**< driver dlist extensions */
 
-
-   GLuint _Facing; /**< This is a hack for 2-sided stencil test.
-                   *
-                   * We don't have a better way to communicate this value from
-                   * swrast_setup to swrast. */
-
    /** \name For debugging/development only */
    /*@{*/
    GLboolean FirstTimeCurrent;
index e7911fec3b5536bf98cdb539bff0cdf4aa1a583b..ca08203d8315178b555cc6e1aa067dc8252a59b5 100644 (file)
@@ -141,6 +141,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 
    INIT_SPAN(line.span, GL_LINE);
    line.span.arrayMask = SPAN_XY | SPAN_COVERAGE;
+   line.span.facing = swrast->PointLineFacing;
    line.xAdj = line.dx / line.len * line.halfWidth;
    line.yAdj = line.dy / line.len * line.halfWidth;
 
index 29609add179d47aece29a8d5e5d2d9c764c77da4..0827b3db9eb90e54491b56461a9aa0fb3a89a1c4 100644 (file)
@@ -65,7 +65,7 @@
    GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
    GLfloat wPlane[4];  /* win[3] */
 #endif
-   GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
+   GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceCullSign;
    
    (void) swrast;
 
    majDx = vMax->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
    majDy = vMax->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
 
+   /* front/back-face determination and cullling */
    {
       const GLfloat botDx = vMid->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
       const GLfloat botDy = vMid->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
         return;
       ltor = (GLboolean) (area < 0.0F);
+
+      span.facing = area * swrast->_BackfaceSign > 0.0F;
    }
 
    /* Plane equation setup:
index 395692565148856f0ea49dbb429c95862509e8ef..3bf9804befc8a682cc2c5d5a409966c6e101bf98 100644 (file)
@@ -117,8 +117,8 @@ _swrast_update_rasterflags( GLcontext *ctx )
 
 
 /**
- * Examine polycon culls tate to compute the _BackfaceSign field.
- * _BackfaceSign will be 0 if no culling, -1 if culling back-faces,
+ * Examine polycon culls tate to compute the _BackfaceCullSign field.
+ * _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces,
  * and 1 if culling front-faces.  The Polygon FrontFace state also
  * factors in.
  */
@@ -149,10 +149,15 @@ _swrast_update_polygon( GLcontext *ctx )
       backface_sign = 0.0;
    }
 
-   SWRAST_CONTEXT(ctx)->_BackfaceSign = backface_sign;
+   SWRAST_CONTEXT(ctx)->_BackfaceCullSign = backface_sign;
+
+   /* This is for front/back-face determination, but not for culling */
+   SWRAST_CONTEXT(ctx)->_BackfaceSign
+      = (ctx->Polygon.FrontFace == GL_CW) ? -1.0 : 1.0;
 }
 
 
+
 /**
  * Update the _PreferPixelFog field to indicate if we need to compute
  * fog blend factors (from the fog coords) per-fragment.
@@ -763,6 +768,12 @@ _swrast_ResetLineStipple( GLcontext *ctx )
    SWRAST_CONTEXT(ctx)->StippleCounter = 0;
 }
 
+void
+_swrast_SetFacing(GLcontext *ctx, GLuint facing)
+{
+   SWRAST_CONTEXT(ctx)->PointLineFacing = facing;
+}
+
 void
 _swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value )
 {
index daa07e15783af7dfd0cd555c8d7390c65d8cf122..aebc80c2080ea10645943e465cda1688b7e6a956 100644 (file)
@@ -128,7 +128,8 @@ typedef struct
     * _swrast_validate_derived():
     */
    GLbitfield _RasterMask;
-   GLfloat _BackfaceSign;
+   GLfloat _BackfaceSign;      /** +1 or -1 */
+   GLfloat _BackfaceCullSign;  /** +1, 0, or -1 */
    GLboolean _PreferPixelFog;    /* Compute fog blend factor per fragment? */
    GLboolean _AnyTextureCombine;
    GLboolean _FogEnabled;
@@ -156,6 +157,7 @@ typedef struct
    /* Working values:
     */
    GLuint StippleCounter;    /**< Line stipple counter */
+   GLuint PointLineFacing;
    GLbitfield NewState;
    GLuint StateChanges;
    GLenum Primitive;    /* current primitive being drawn (ala glBegin) */
index 4067fd688674a6a23d2feb503db056dab77a97df..767e485ede20ea9c93560ec64dab9891dddf6479 100644 (file)
@@ -120,7 +120,7 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
    /* if running a GLSL program (not ARB_fragment_program) */
    if (ctx->Shader.CurrentProgram) {
       /* Store front/back facing value in register FOGC.Y */
-      machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing;
+      machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) span->facing;
    }
 
    machine->CurElement = col;
index 1accfc67e2ce66ff1f32e0c10845913a1bf2e23e..1abf8d6c7f3d1a8c84a95787abd2e9a20ff74358 100644 (file)
@@ -308,6 +308,9 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    span.interpMask = interpFlags;
    span.arrayMask = SPAN_XY;
 
+   span.facing = swrast->PointLineFacing;
+
+
    /*
     * Draw
     */
index dd664b980ed1907307f24589f35d0110357156ec..d60e175baa0f5d4df075e1364b49a2feb64b29b2 100644 (file)
@@ -106,6 +106,8 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
    INIT_SPAN(span, GL_POINT);
    span.interpMask = SPAN_Z | SPAN_RGBA;
 
+   span.facing = swrast->PointLineFacing;
+
    span.red   = ChanToFixed(vert->color[0]);
    span.green = ChanToFixed(vert->color[1]);
    span.blue  = ChanToFixed(vert->color[2]);
@@ -280,6 +282,8 @@ smooth_point(GLcontext *ctx, const SWvertex *vert)
    span.interpMask = SPAN_Z | SPAN_RGBA;
    span.arrayMask = SPAN_COVERAGE | SPAN_MASK;
 
+   span.facing = swrast->PointLineFacing;
+
    span.red   = ChanToFixed(vert->color[0]);
    span.green = ChanToFixed(vert->color[1]);
    span.blue  = ChanToFixed(vert->color[2]);
@@ -386,6 +390,7 @@ large_point(GLcontext *ctx, const SWvertex *vert)
    /* span init */
    INIT_SPAN(span, GL_POINT);
    span.arrayMask = SPAN_XY;
+   span.facing = swrast->PointLineFacing;
 
    if (ciMode) {
       span.interpMask = SPAN_Z | SPAN_INDEX;
@@ -492,7 +497,8 @@ pixel_point(GLcontext *ctx, const SWvertex *vert)
 
    /* check if we need to flush */
    if (span->end >= MAX_WIDTH ||
-       (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT))) {
+       (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT)) ||
+       span->facing != swrast->PointLineFacing) {
       if (ciMode)
          _swrast_write_index_span(ctx, span);
       else
@@ -502,6 +508,8 @@ pixel_point(GLcontext *ctx, const SWvertex *vert)
 
    count = span->end;
 
+   span->facing = swrast->PointLineFacing;
+
    /* fragment attributes */
    if (ciMode) {
       span->array->index[count] = (GLuint) vert->attrib[FRAG_ATTRIB_CI][0];
index c255545217318eaee46305ed17345f1bab33412c..938cdefa561450b83034d499b3e82821bdc4e0ae 100644 (file)
@@ -58,7 +58,7 @@ _swrast_culltriangle( GLcontext *ctx,
    GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
    GLfloat c = ex*fy-ey*fx;
 
-   if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0)
+   if (c * SWRAST_CONTEXT(ctx)->_BackfaceCullSign > 0)
       return 0;
 
    return 1;
index cded4a6c1c414a1715f66b365efe8162a06bfec6..c609210c0ec9f7bc0ee33edce200dddd901ff872 100644 (file)
@@ -136,7 +136,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
    EdgeT eMaj, eTop, eBot;
    GLfloat oneOverArea;
    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
-   GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
+   GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceCullSign;
    const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
 
@@ -235,6 +235,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
    {
       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
       /* Do backface culling */
+
       if (area * bf < 0.0)
          return;
 
@@ -242,10 +243,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          return;
 
       oneOverArea = 1.0F / area;
-   }
 
-
-   span.facing = ctx->_Facing; /* for 2-sided stencil test */
+      /* 0 = front, 1 = back */
+      span.facing = oneOverArea * swrast->_BackfaceSign > 0.0F;
+   }
 
    /* Edge setup.  For a triangle strip these could be reused... */
    {
index 85a27fd55bf534cdce0011fa63f525cf7c4fcf6d..047f7991e645ce4a96bb60bc314530d33dff279a 100644 (file)
@@ -143,6 +143,13 @@ _swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value);
 extern void
 _swrast_ResetLineStipple( GLcontext *ctx );
 
+/**
+ * Indicates front/back facing for subsequent points/lines when drawing
+ * unfilled polygons.  Needed for two-side stencil.
+ */
+extern void
+_swrast_SetFacing(GLcontext *ctx, GLuint facing);
+
 /* These will always render the correct point/line/triangle for the
  * current state.
  *
index a9c7d941e5b17e09d6b95a449025ffaf8df00646..a4f949ddfe8fc631ec35df7b69ac1cbd556520e1 100644 (file)
@@ -201,6 +201,9 @@ _swsetup_RenderStart( GLcontext *ctx )
 
    swsetup->NewState = 0;
 
+   /* This will change if drawing unfilled tris */
+   _swrast_SetFacing(ctx, 0);
+
    _swrast_render_start(ctx);
 
    /* Important */
index b4207f2c64a60c4e93ab4421a376efac87bd949c..4817d239321801eb88868b1a913805f232022e84 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.1
+ * Version:  7.1
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  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"),
@@ -68,6 +68,8 @@ static void _swsetup_render_line_tri( GLcontext *ctx,
          return;
    }
 
+   _swrast_SetFacing(ctx, facing);
+
    if (ctx->Light.ShadeModel == GL_FLAT) {
       COPY_CHAN4(c[0], v0->color);
       COPY_CHAN4(c[1], v1->color);
@@ -127,6 +129,8 @@ static void _swsetup_render_point_tri( GLcontext *ctx,
          return;
    }
 
+   _swrast_SetFacing(ctx, facing);
+
    if (ctx->Light.ShadeModel == GL_FLAT) {
       /* save colors/indexes for v0, v1 vertices */
       COPY_CHAN4(c[0], v0->color);
@@ -311,6 +315,4 @@ void _swsetup_choose_trifuncs( GLcontext *ctx )
    tnl->Driver.Render.Quad = quad_tab[ind];
    tnl->Driver.Render.Line = swsetup_line;
    tnl->Driver.Render.Points = swsetup_points;
-
-   ctx->_Facing = 0;
 }
index 7d1bc234650ee511b1b398aafdb3e3dc711bb6ab..97d2f4a16b19d60604de2bc4d5b7294c301d4692 100644 (file)
@@ -49,7 +49,6 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
    v[1] = &verts[e1];
    v[2] = &verts[e2];
 
-
    if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT))
    {
       GLfloat ex = v[0]->attrib[FRAG_ATTRIB_WPOS][0] - v[2]->attrib[FRAG_ATTRIB_WPOS][0];
@@ -61,7 +60,6 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
       if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT))
       {
         facing = (cc < 0.0) ^ ctx->Polygon._FrontBit;
-         ctx->_Facing = facing;
 
         if (IND & SS_UNFILLED_BIT)
            mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode;