[cogl] Use clockwise face winding for offscreen buffers with culling enabled

Because Cogl defines the origin for texture as top left and offscreen draw
buffers can be used to render to textures, we (internally) force all
offscreen rendering to be upside down. (because OpenGL defines the origin
to be bottom left)

By forcing the users scene to be rendered upside down though we also reverse
the winding order of all the drawn triangles which may interfere with the
users use of backface culling.  This patch ensures that we reverse the
winding order for a front face (if culling is in use) while rendering
offscreen so we don't conflict with the users back face culling.
This commit is contained in:
Robert Bragg 2009-10-22 19:01:52 +01:00
parent 1acf5cc36f
commit 181bf92086
7 changed files with 48 additions and 0 deletions

View File

@ -68,6 +68,7 @@ cogl_create_context (void)
_context->color_alpha = 0;
_context->enable_backface_culling = FALSE;
_context->flushed_front_winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE;
_context->indirect = gl_is_indirect;
@ -141,6 +142,7 @@ cogl_create_context (void)
enable_flags =
_cogl_material_get_cogl_enable_flags (_context->source_material);
cogl_enable (enable_flags);
_cogl_flush_face_winding ();
return TRUE;
}

View File

@ -49,6 +49,7 @@ typedef struct
guint8 color_alpha;
gboolean enable_backface_culling;
CoglFrontWinding flushed_front_winding;
gboolean indirect;

View File

@ -34,6 +34,12 @@ typedef enum
COGL_MATRIX_TEXTURE
} CoglMatrixMode;
typedef enum
{
COGL_FRONT_WINDING_CLOCKWISE,
COGL_FRONT_WINDING_COUNTER_CLOCKWISE
} CoglFrontWinding;
#ifdef HAVE_COGL_GLES2
typedef enum {
COGL_BOXED_NONE,
@ -105,4 +111,7 @@ _cogl_destroy_texture_units (void);
void _cogl_flush_matrix_stacks (void);
void
_cogl_flush_face_winding (void);
#endif /* __COGL_INTERNAL_H */

View File

@ -302,6 +302,7 @@ _cogl_journal_flush_material_and_entries (CoglJournalEntry *batch_start,
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
cogl_enable (enable_flags);
_cogl_flush_face_winding ();
/* If we haven't transformed the quads in software then we need to also break
* up batches according to changes in the modelview matrix... */

View File

@ -979,6 +979,7 @@ cogl_polygon (CoglTextureVertex *vertices,
}
cogl_enable (enable_flags);
_cogl_flush_face_winding ();
GE (glVertexPointer (3, GL_FLOAT, stride_bytes, v));

View File

@ -1683,6 +1683,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
_cogl_flush_face_winding ();
}
static void

View File

@ -284,6 +284,38 @@ cogl_get_backface_culling_enabled (void)
return ctx->enable_backface_culling;
}
void
_cogl_flush_face_winding (void)
{
CoglFrontWinding winding;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* The front face winding doesn't matter if we aren't performing any
* backface culling... */
if (!ctx->enable_backface_culling)
return;
/* NB: We use a clockwise face winding order when drawing offscreen because
* all offscreen rendering is done upside down resulting in reversed winding
* for all triangles.
*/
if (cogl_is_offscreen (_cogl_get_draw_buffer ()))
winding = COGL_FRONT_WINDING_CLOCKWISE;
else
winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE;
if (winding != ctx->flushed_front_winding)
{
if (winding == COGL_FRONT_WINDING_CLOCKWISE)
GE (glFrontFace (GL_CW));
else
GE (glFrontFace (GL_CCW));
ctx->flushed_front_winding = winding;
}
}
void
cogl_set_source_color (const CoglColor *color)
{
@ -909,6 +941,7 @@ cogl_begin_gl (void)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
_cogl_flush_face_winding ();
/* Disable all client texture coordinate arrays */
for (i = 0; i < ctx->n_texcoord_arrays_enabled; i++)