summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--progs/trivial/tri-cull.c14
-rw-r--r--src/mesa/pipe/draw/draw_cull.c12
-rw-r--r--src/mesa/pipe/draw/draw_twoside.c12
-rw-r--r--src/mesa/state_tracker/st_atom_setup.c32
4 files changed, 46 insertions, 24 deletions
diff --git a/progs/trivial/tri-cull.c b/progs/trivial/tri-cull.c
index af26cb0b2b..2eead84115 100644
--- a/progs/trivial/tri-cull.c
+++ b/progs/trivial/tri-cull.c
@@ -29,6 +29,7 @@
static GLenum doubleBuffer;
static GLint cullmode = 0;
+static GLenum front = GL_CCW; /* GL default */
static void cull(void)
{
@@ -76,11 +77,16 @@ static void Reshape(int width, int height)
static void Key(unsigned char key, int x, int y)
{
switch (key) {
- case 27:
- exit(1);
+ case 27:
+ exit(1);
case 'c':
cull();
break;
+ case 'f':
+ front = ((front == GL_CCW) ? GL_CW : GL_CCW);
+ glFrontFace(front);
+ printf("front face = %s\n", front == GL_CCW ? "GL_CCW" : "GL_CW");
+ break;
default:
return;
}
@@ -92,7 +98,7 @@ static void Draw(void)
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
- /* back-facing */
+ /* CCW / front-facing */
glColor3f(0,0,.7);
glVertex3f(-0.1, -0.9, -30.0);
glColor3f(.8,0,0);
@@ -100,7 +106,7 @@ static void Draw(void)
glColor3f(0,.9,0);
glVertex3f(-0.9, 0.0, -30.0);
- /* front-facing */
+ /* CW / back-facing */
glColor3f(0,0,.7);
glVertex3f( 0.1, -0.9, -30.0);
glColor3f(.8,0,0);
diff --git a/src/mesa/pipe/draw/draw_cull.c b/src/mesa/pipe/draw/draw_cull.c
index 863686f150..e563f9f45f 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 e86123e84d..9f26335fb6 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 8b95ea958e..6ee96f6178 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
@@ -92,14 +98,18 @@ static void update_setup_state( struct st_context *st )
if (ctx->Light.ShadeModel == GL_FLAT)
setup.flatshade = 1;
- /* _NEW_LIGHT
+ /* _NEW_LIGHT | _NEW_PROGRAM
*
- * Not sure about the light->enabled requirement - does this still
- * apply??
+ * Back-face colors can come from traditional lighting (when
+ * GL_LIGHT_MODEL_TWO_SIDE is set) or from vertex programs (when
+ * GL_VERTEX_PROGRAM_TWO_SIDE is set). Note the logic here.
*/
- if (ctx->Light.Enabled &&
- ctx->Light.Model.TwoSide)
+ if (ctx->VertexProgram._Enabled) {
+ setup.light_twoside = ctx->VertexProgram.TwoSideEnabled;
+ }
+ else if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
setup.light_twoside = 1;
+ }
/* _NEW_POLYGON
*/