From fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bb Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 30 Nov 2007 13:01:57 -0700 Subject: [PATCH] fix broken two-sided stencil --- src/mesa/main/context.c | 1 - src/mesa/main/mtypes.h | 6 ------ src/mesa/swrast/s_aalinetemp.h | 1 + src/mesa/swrast/s_aatritemp.h | 5 ++++- src/mesa/swrast/s_context.c | 17 ++++++++++++++--- src/mesa/swrast/s_context.h | 4 +++- src/mesa/swrast/s_fragprog.c | 2 +- src/mesa/swrast/s_linetemp.h | 3 +++ src/mesa/swrast/s_points.c | 10 +++++++++- src/mesa/swrast/s_triangle.c | 2 +- src/mesa/swrast/s_tritemp.h | 9 +++++---- src/mesa/swrast/swrast.h | 7 +++++++ src/mesa/swrast_setup/ss_context.c | 3 +++ src/mesa/swrast_setup/ss_triangle.c | 10 ++++++---- src/mesa/swrast_setup/ss_tritmp.h | 2 -- 15 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 08db12b1b67..2ae0e1221d6 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -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; } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 1fbfeb7447b..94b70943889 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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; diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h index e7911fec3b5..ca08203d831 100644 --- a/src/mesa/swrast/s_aalinetemp.h +++ b/src/mesa/swrast/s_aalinetemp.h @@ -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; diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h index 29609add179..0827b3db9eb 100644 --- a/src/mesa/swrast/s_aatritemp.h +++ b/src/mesa/swrast/s_aatritemp.h @@ -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; @@ -104,6 +104,7 @@ 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]; @@ -112,6 +113,8 @@ 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: diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 39569256514..3bf9804befc 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -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 ) { diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index daa07e15783..aebc80c2080 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -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) */ diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 4067fd68867..767e485ede2 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -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; diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h index 1accfc67e2c..1abf8d6c7f3 100644 --- a/src/mesa/swrast/s_linetemp.h +++ b/src/mesa/swrast/s_linetemp.h @@ -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 */ diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index dd664b980ed..d60e175baa0 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -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]; diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index c2555452173..938cdefa561 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -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; diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index cded4a6c1c4..c609210c0ec 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -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... */ { diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 85a27fd55bf..047f7991e64 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -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. * diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index a9c7d941e5b..a4f949ddfe8 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -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 */ diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c index b4207f2c64a..4817d239321 100644 --- a/src/mesa/swrast_setup/ss_triangle.c +++ b/src/mesa/swrast_setup/ss_triangle.c @@ -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; } diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h index 7d1bc234650..97d2f4a16b1 100644 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ b/src/mesa/swrast_setup/ss_tritmp.h @@ -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; -- 2.30.2