From: Brian Date: Fri, 13 Jul 2007 20:22:46 +0000 (-0600) Subject: Fix more polygon winding, culling confusion. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=dc313b578386dc07f4916fba98da061af3ab18e5;p=mesa.git Fix more polygon winding, culling confusion. If the determinant of the triangle is positive, its winding is CCW (right-handed coord system). --- diff --git a/src/mesa/pipe/draw/draw_cull.c b/src/mesa/pipe/draw/draw_cull.c index 863686f1502..e563f9f45f6 100644 --- a/src/mesa/pipe/draw/draw_cull.c +++ b/src/mesa/pipe/draw/draw_cull.c @@ -40,7 +40,7 @@ struct cull_stage { struct draw_stage stage; - GLuint mode; /**< one of PIPE_WINDING_x */ + GLuint winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ }; @@ -54,7 +54,7 @@ static void cull_begin( struct draw_stage *stage ) { struct cull_stage *cull = cull_stage(stage); - cull->mode = stage->draw->setup.cull_mode; + cull->winding = stage->draw->setup.cull_mode; stage->next->begin( stage->next ); } @@ -78,10 +78,12 @@ static void cull_tri( struct draw_stage *stage, header->det = ex * fy - ey * fx; if (header->det != 0) { - /* non-zero area */ - GLuint mode = (header->det > 0) ? PIPE_WINDING_CW : PIPE_WINDING_CCW; + /* if (det > 0 then Z points toward camera and triangle is + * counter-clockwise winding. + */ + GLuint winding = (header->det > 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; - if ((mode & cull_stage(stage)->mode) == 0) { + if ((winding & cull_stage(stage)->winding) == 0) { /* triangle is not culled, pass to next stage */ stage->next->tri( stage->next, header ); } diff --git a/src/mesa/pipe/draw/draw_twoside.c b/src/mesa/pipe/draw/draw_twoside.c index e86123e84db..9f26335fb65 100644 --- a/src/mesa/pipe/draw/draw_twoside.c +++ b/src/mesa/pipe/draw/draw_twoside.c @@ -35,8 +35,7 @@ struct twoside_stage { struct draw_stage stage; - - GLfloat facing; + GLfloat sign; /**< +1 or -1 */ const GLuint *lookup; }; @@ -51,7 +50,12 @@ static void twoside_begin( struct draw_stage *stage ) { struct twoside_stage *twoside = twoside_stage(stage); - twoside->facing = (stage->draw->setup.front_winding == PIPE_WINDING_CW) ? 1 : -1; + /* + * We'll multiply the primitive's determinant by this sign to determine + * if the triangle is back-facing (negative). + * sign = 1 for CCW, -1 for CW + */ + twoside->sign = (stage->draw->setup.front_winding == PIPE_WINDING_CCW) ? 1 : -1; stage->next->begin( stage->next ); } @@ -94,7 +98,7 @@ static void twoside_tri( struct draw_stage *stage, { struct twoside_stage *twoside = twoside_stage(stage); - if (header->det * twoside->facing < 0) { + if (header->det * twoside->sign < 0.0) { /* this is a back-facing triangle */ struct prim_header tmp; diff --git a/src/mesa/state_tracker/st_atom_setup.c b/src/mesa/state_tracker/st_atom_setup.c index 8b95ea958eb..08f7a8a7325 100644 --- a/src/mesa/state_tracker/st_atom_setup.c +++ b/src/mesa/state_tracker/st_atom_setup.c @@ -78,13 +78,19 @@ static void update_setup_state( struct st_context *st ) /* _NEW_POLYGON, _NEW_BUFFERS */ { - setup.front_winding = PIPE_WINDING_CW; - + if (ctx->Polygon.FrontFace == GL_CCW) + setup.front_winding = PIPE_WINDING_CCW; + else + setup.front_winding = PIPE_WINDING_CW; + + /* XXX + * I think the intention here is that user-created framebuffer objects + * use Y=0=TOP layout instead of OpenGL's normal Y=0=bottom layout. + * Flipping Y changes CW to CCW and vice-versa. + * But this is an implementation/driver-specific artifact - remove... + */ if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) - setup.front_winding ^= PIPE_WINDING_BOTH; - - if (ctx->Polygon.FrontFace != GL_CCW) - setup.front_winding ^= PIPE_WINDING_BOTH; + setup.front_winding ^= PIPE_WINDING_BOTH; } /* _NEW_LIGHT