[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 b2ebb7db48
commit 764cca75b4
7 changed files with 48 additions and 0 deletions

View File

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

View File

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

View File

@ -34,6 +34,12 @@ typedef enum
COGL_MATRIX_TEXTURE COGL_MATRIX_TEXTURE
} CoglMatrixMode; } CoglMatrixMode;
typedef enum
{
COGL_FRONT_WINDING_CLOCKWISE,
COGL_FRONT_WINDING_COUNTER_CLOCKWISE
} CoglFrontWinding;
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
typedef enum { typedef enum {
COGL_BOXED_NONE, COGL_BOXED_NONE,
@ -105,4 +111,7 @@ _cogl_destroy_texture_units (void);
void _cogl_flush_matrix_stacks (void); void _cogl_flush_matrix_stacks (void);
void
_cogl_flush_face_winding (void);
#endif /* __COGL_INTERNAL_H */ #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_VERTEX_ARRAY;
enable_flags |= COGL_ENABLE_COLOR_ARRAY; enable_flags |= COGL_ENABLE_COLOR_ARRAY;
cogl_enable (enable_flags); cogl_enable (enable_flags);
_cogl_flush_face_winding ();
/* If we haven't transformed the quads in software then we need to also break /* If we haven't transformed the quads in software then we need to also break
* up batches according to changes in the modelview matrix... */ * up batches according to changes in the modelview matrix... */

View File

@ -979,6 +979,7 @@ cogl_polygon (CoglTextureVertex *vertices,
} }
cogl_enable (enable_flags); cogl_enable (enable_flags);
_cogl_flush_face_winding ();
GE (glVertexPointer (3, GL_FLOAT, stride_bytes, v)); 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; enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags); cogl_enable (enable_flags);
_cogl_flush_face_winding ();
} }
static void static void

View File

@ -284,6 +284,38 @@ cogl_get_backface_culling_enabled (void)
return ctx->enable_backface_culling; 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 void
cogl_set_source_color (const CoglColor *color) cogl_set_source_color (const CoglColor *color)
{ {
@ -909,6 +941,7 @@ cogl_begin_gl (void)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING; enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags); cogl_enable (enable_flags);
_cogl_flush_face_winding ();
/* Disable all client texture coordinate arrays */ /* Disable all client texture coordinate arrays */
for (i = 0; i < ctx->n_texcoord_arrays_enabled; i++) for (i = 0; i < ctx->n_texcoord_arrays_enabled; i++)