If the determinant of the triangle is positive, its winding is CCW (right-handed coord system).
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) */
};
{
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 );
}
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 );
}
struct twoside_stage {
struct draw_stage stage;
-
- GLfloat facing;
+ GLfloat sign; /**< +1 or -1 */
const GLuint *lookup;
};
{
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 );
}
{
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;
/* _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