Fix more polygon winding, culling confusion.
If the determinant of the triangle is positive, its winding is CCW (right-handed coord system).
This commit is contained in:
parent
2bf4a500de
commit
dc313b5783
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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->DrawBuffer && ctx->DrawBuffer->Name != 0)
|
||||
setup.front_winding ^= PIPE_WINDING_BOTH;
|
||||
if (ctx->Polygon.FrontFace == GL_CCW)
|
||||
setup.front_winding = PIPE_WINDING_CCW;
|
||||
else
|
||||
setup.front_winding = PIPE_WINDING_CW;
|
||||
|
||||
if (ctx->Polygon.FrontFace != GL_CCW)
|
||||
setup.front_winding ^= PIPE_WINDING_BOTH;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* _NEW_LIGHT
|
||||
|
|
Loading…
Reference in New Issue