fix broken two-sided stencil
This commit is contained in:
@@ -992,7 +992,6 @@ init_attrib_groups(GLcontext *ctx)
|
|||||||
/* Miscellaneous */
|
/* Miscellaneous */
|
||||||
ctx->NewState = _NEW_ALL;
|
ctx->NewState = _NEW_ALL;
|
||||||
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
|
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
|
||||||
ctx->_Facing = 0;
|
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
@@ -3059,12 +3059,6 @@ struct __GLcontextRec
|
|||||||
|
|
||||||
struct gl_list_extensions ListExt; /**< driver dlist extensions */
|
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 */
|
/** \name For debugging/development only */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
GLboolean FirstTimeCurrent;
|
GLboolean FirstTimeCurrent;
|
||||||
|
@@ -141,6 +141,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
|
|||||||
|
|
||||||
INIT_SPAN(line.span, GL_LINE);
|
INIT_SPAN(line.span, GL_LINE);
|
||||||
line.span.arrayMask = SPAN_XY | SPAN_COVERAGE;
|
line.span.arrayMask = SPAN_XY | SPAN_COVERAGE;
|
||||||
|
line.span.facing = swrast->PointLineFacing;
|
||||||
line.xAdj = line.dx / line.len * line.halfWidth;
|
line.xAdj = line.dx / line.len * line.halfWidth;
|
||||||
line.yAdj = line.dy / line.len * line.halfWidth;
|
line.yAdj = line.dy / line.len * line.halfWidth;
|
||||||
|
|
||||||
|
@@ -65,7 +65,7 @@
|
|||||||
GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
|
GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
|
||||||
GLfloat wPlane[4]; /* win[3] */
|
GLfloat wPlane[4]; /* win[3] */
|
||||||
#endif
|
#endif
|
||||||
GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
|
GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceCullSign;
|
||||||
|
|
||||||
(void) swrast;
|
(void) swrast;
|
||||||
|
|
||||||
@@ -104,6 +104,7 @@
|
|||||||
majDx = vMax->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
|
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];
|
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 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];
|
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))
|
if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
|
||||||
return;
|
return;
|
||||||
ltor = (GLboolean) (area < 0.0F);
|
ltor = (GLboolean) (area < 0.0F);
|
||||||
|
|
||||||
|
span.facing = area * swrast->_BackfaceSign > 0.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Plane equation setup:
|
/* Plane equation setup:
|
||||||
|
@@ -117,8 +117,8 @@ _swrast_update_rasterflags( GLcontext *ctx )
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Examine polycon culls tate to compute the _BackfaceSign field.
|
* Examine polycon culls tate to compute the _BackfaceCullSign field.
|
||||||
* _BackfaceSign will be 0 if no culling, -1 if culling back-faces,
|
* _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces,
|
||||||
* and 1 if culling front-faces. The Polygon FrontFace state also
|
* and 1 if culling front-faces. The Polygon FrontFace state also
|
||||||
* factors in.
|
* factors in.
|
||||||
*/
|
*/
|
||||||
@@ -149,10 +149,15 @@ _swrast_update_polygon( GLcontext *ctx )
|
|||||||
backface_sign = 0.0;
|
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
|
* Update the _PreferPixelFog field to indicate if we need to compute
|
||||||
* fog blend factors (from the fog coords) per-fragment.
|
* fog blend factors (from the fog coords) per-fragment.
|
||||||
@@ -763,6 +768,12 @@ _swrast_ResetLineStipple( GLcontext *ctx )
|
|||||||
SWRAST_CONTEXT(ctx)->StippleCounter = 0;
|
SWRAST_CONTEXT(ctx)->StippleCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_swrast_SetFacing(GLcontext *ctx, GLuint facing)
|
||||||
|
{
|
||||||
|
SWRAST_CONTEXT(ctx)->PointLineFacing = facing;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value )
|
_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value )
|
||||||
{
|
{
|
||||||
|
@@ -128,7 +128,8 @@ typedef struct
|
|||||||
* _swrast_validate_derived():
|
* _swrast_validate_derived():
|
||||||
*/
|
*/
|
||||||
GLbitfield _RasterMask;
|
GLbitfield _RasterMask;
|
||||||
GLfloat _BackfaceSign;
|
GLfloat _BackfaceSign; /** +1 or -1 */
|
||||||
|
GLfloat _BackfaceCullSign; /** +1, 0, or -1 */
|
||||||
GLboolean _PreferPixelFog; /* Compute fog blend factor per fragment? */
|
GLboolean _PreferPixelFog; /* Compute fog blend factor per fragment? */
|
||||||
GLboolean _AnyTextureCombine;
|
GLboolean _AnyTextureCombine;
|
||||||
GLboolean _FogEnabled;
|
GLboolean _FogEnabled;
|
||||||
@@ -156,6 +157,7 @@ typedef struct
|
|||||||
/* Working values:
|
/* Working values:
|
||||||
*/
|
*/
|
||||||
GLuint StippleCounter; /**< Line stipple counter */
|
GLuint StippleCounter; /**< Line stipple counter */
|
||||||
|
GLuint PointLineFacing;
|
||||||
GLbitfield NewState;
|
GLbitfield NewState;
|
||||||
GLuint StateChanges;
|
GLuint StateChanges;
|
||||||
GLenum Primitive; /* current primitive being drawn (ala glBegin) */
|
GLenum Primitive; /* current primitive being drawn (ala glBegin) */
|
||||||
|
@@ -120,7 +120,7 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
|
|||||||
/* if running a GLSL program (not ARB_fragment_program) */
|
/* if running a GLSL program (not ARB_fragment_program) */
|
||||||
if (ctx->Shader.CurrentProgram) {
|
if (ctx->Shader.CurrentProgram) {
|
||||||
/* Store front/back facing value in register FOGC.Y */
|
/* 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;
|
machine->CurElement = col;
|
||||||
|
@@ -308,6 +308,9 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
|
|||||||
span.interpMask = interpFlags;
|
span.interpMask = interpFlags;
|
||||||
span.arrayMask = SPAN_XY;
|
span.arrayMask = SPAN_XY;
|
||||||
|
|
||||||
|
span.facing = swrast->PointLineFacing;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draw
|
* Draw
|
||||||
*/
|
*/
|
||||||
|
@@ -106,6 +106,8 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
|
|||||||
INIT_SPAN(span, GL_POINT);
|
INIT_SPAN(span, GL_POINT);
|
||||||
span.interpMask = SPAN_Z | SPAN_RGBA;
|
span.interpMask = SPAN_Z | SPAN_RGBA;
|
||||||
|
|
||||||
|
span.facing = swrast->PointLineFacing;
|
||||||
|
|
||||||
span.red = ChanToFixed(vert->color[0]);
|
span.red = ChanToFixed(vert->color[0]);
|
||||||
span.green = ChanToFixed(vert->color[1]);
|
span.green = ChanToFixed(vert->color[1]);
|
||||||
span.blue = ChanToFixed(vert->color[2]);
|
span.blue = ChanToFixed(vert->color[2]);
|
||||||
@@ -280,6 +282,8 @@ smooth_point(GLcontext *ctx, const SWvertex *vert)
|
|||||||
span.interpMask = SPAN_Z | SPAN_RGBA;
|
span.interpMask = SPAN_Z | SPAN_RGBA;
|
||||||
span.arrayMask = SPAN_COVERAGE | SPAN_MASK;
|
span.arrayMask = SPAN_COVERAGE | SPAN_MASK;
|
||||||
|
|
||||||
|
span.facing = swrast->PointLineFacing;
|
||||||
|
|
||||||
span.red = ChanToFixed(vert->color[0]);
|
span.red = ChanToFixed(vert->color[0]);
|
||||||
span.green = ChanToFixed(vert->color[1]);
|
span.green = ChanToFixed(vert->color[1]);
|
||||||
span.blue = ChanToFixed(vert->color[2]);
|
span.blue = ChanToFixed(vert->color[2]);
|
||||||
@@ -386,6 +390,7 @@ large_point(GLcontext *ctx, const SWvertex *vert)
|
|||||||
/* span init */
|
/* span init */
|
||||||
INIT_SPAN(span, GL_POINT);
|
INIT_SPAN(span, GL_POINT);
|
||||||
span.arrayMask = SPAN_XY;
|
span.arrayMask = SPAN_XY;
|
||||||
|
span.facing = swrast->PointLineFacing;
|
||||||
|
|
||||||
if (ciMode) {
|
if (ciMode) {
|
||||||
span.interpMask = SPAN_Z | SPAN_INDEX;
|
span.interpMask = SPAN_Z | SPAN_INDEX;
|
||||||
@@ -492,7 +497,8 @@ pixel_point(GLcontext *ctx, const SWvertex *vert)
|
|||||||
|
|
||||||
/* check if we need to flush */
|
/* check if we need to flush */
|
||||||
if (span->end >= MAX_WIDTH ||
|
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)
|
if (ciMode)
|
||||||
_swrast_write_index_span(ctx, span);
|
_swrast_write_index_span(ctx, span);
|
||||||
else
|
else
|
||||||
@@ -502,6 +508,8 @@ pixel_point(GLcontext *ctx, const SWvertex *vert)
|
|||||||
|
|
||||||
count = span->end;
|
count = span->end;
|
||||||
|
|
||||||
|
span->facing = swrast->PointLineFacing;
|
||||||
|
|
||||||
/* fragment attributes */
|
/* fragment attributes */
|
||||||
if (ciMode) {
|
if (ciMode) {
|
||||||
span->array->index[count] = (GLuint) vert->attrib[FRAG_ATTRIB_CI][0];
|
span->array->index[count] = (GLuint) vert->attrib[FRAG_ATTRIB_CI][0];
|
||||||
|
@@ -58,7 +58,7 @@ _swrast_culltriangle( GLcontext *ctx,
|
|||||||
GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
|
GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
|
||||||
GLfloat c = ex*fy-ey*fx;
|
GLfloat c = ex*fy-ey*fx;
|
||||||
|
|
||||||
if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0)
|
if (c * SWRAST_CONTEXT(ctx)->_BackfaceCullSign > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@@ -136,7 +136,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
|
|||||||
EdgeT eMaj, eTop, eBot;
|
EdgeT eMaj, eTop, eBot;
|
||||||
GLfloat oneOverArea;
|
GLfloat oneOverArea;
|
||||||
const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */
|
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 */
|
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;
|
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;
|
const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
|
||||||
/* Do backface culling */
|
/* Do backface culling */
|
||||||
|
|
||||||
if (area * bf < 0.0)
|
if (area * bf < 0.0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -242,11 +243,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
oneOverArea = 1.0F / area;
|
oneOverArea = 1.0F / area;
|
||||||
|
|
||||||
|
/* 0 = front, 1 = back */
|
||||||
|
span.facing = oneOverArea * swrast->_BackfaceSign > 0.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
span.facing = ctx->_Facing; /* for 2-sided stencil test */
|
|
||||||
|
|
||||||
/* Edge setup. For a triangle strip these could be reused... */
|
/* Edge setup. For a triangle strip these could be reused... */
|
||||||
{
|
{
|
||||||
eMaj.fsy = FixedCeil(vMin_fy);
|
eMaj.fsy = FixedCeil(vMin_fy);
|
||||||
|
@@ -143,6 +143,13 @@ _swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value);
|
|||||||
extern void
|
extern void
|
||||||
_swrast_ResetLineStipple( GLcontext *ctx );
|
_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
|
/* These will always render the correct point/line/triangle for the
|
||||||
* current state.
|
* current state.
|
||||||
*
|
*
|
||||||
|
@@ -201,6 +201,9 @@ _swsetup_RenderStart( GLcontext *ctx )
|
|||||||
|
|
||||||
swsetup->NewState = 0;
|
swsetup->NewState = 0;
|
||||||
|
|
||||||
|
/* This will change if drawing unfilled tris */
|
||||||
|
_swrast_SetFacing(ctx, 0);
|
||||||
|
|
||||||
_swrast_render_start(ctx);
|
_swrast_render_start(ctx);
|
||||||
|
|
||||||
/* Important */
|
/* Important */
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -68,6 +68,8 @@ static void _swsetup_render_line_tri( GLcontext *ctx,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_swrast_SetFacing(ctx, facing);
|
||||||
|
|
||||||
if (ctx->Light.ShadeModel == GL_FLAT) {
|
if (ctx->Light.ShadeModel == GL_FLAT) {
|
||||||
COPY_CHAN4(c[0], v0->color);
|
COPY_CHAN4(c[0], v0->color);
|
||||||
COPY_CHAN4(c[1], v1->color);
|
COPY_CHAN4(c[1], v1->color);
|
||||||
@@ -127,6 +129,8 @@ static void _swsetup_render_point_tri( GLcontext *ctx,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_swrast_SetFacing(ctx, facing);
|
||||||
|
|
||||||
if (ctx->Light.ShadeModel == GL_FLAT) {
|
if (ctx->Light.ShadeModel == GL_FLAT) {
|
||||||
/* save colors/indexes for v0, v1 vertices */
|
/* save colors/indexes for v0, v1 vertices */
|
||||||
COPY_CHAN4(c[0], v0->color);
|
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.Quad = quad_tab[ind];
|
||||||
tnl->Driver.Render.Line = swsetup_line;
|
tnl->Driver.Render.Line = swsetup_line;
|
||||||
tnl->Driver.Render.Points = swsetup_points;
|
tnl->Driver.Render.Points = swsetup_points;
|
||||||
|
|
||||||
ctx->_Facing = 0;
|
|
||||||
}
|
}
|
||||||
|
@@ -49,7 +49,6 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
|
|||||||
v[1] = &verts[e1];
|
v[1] = &verts[e1];
|
||||||
v[2] = &verts[e2];
|
v[2] = &verts[e2];
|
||||||
|
|
||||||
|
|
||||||
if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT))
|
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];
|
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))
|
if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT))
|
||||||
{
|
{
|
||||||
facing = (cc < 0.0) ^ ctx->Polygon._FrontBit;
|
facing = (cc < 0.0) ^ ctx->Polygon._FrontBit;
|
||||||
ctx->_Facing = facing;
|
|
||||||
|
|
||||||
if (IND & SS_UNFILLED_BIT)
|
if (IND & SS_UNFILLED_BIT)
|
||||||
mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode;
|
mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode;
|
||||||
|
Reference in New Issue
Block a user