Make backface culling be part of the legacy state

This adds an internal function to set the backface culling state on a
pipeline. This includes properties to set the culling mode (front,
back or both) and also to set which face is considered the front
(COGL_WINDING_CLOCKWISE or COGL_WINDING_COUNTER_CLOCKWISE). The actual
front face flushed to GL depends on whether we are rendering to an
offscreen buffer or not. This means that when changing between on- and
off- screen framebuffers it now checks whether the last flushed
pipeline has backface culling enabled and forces a reflush of the cull
face state if so.

The backface culling is now set on a pipeline as part of the legacy
state. This is important because some code in Cogl assumes it can
flush a temporary pipeline to revert to a known state, but previously
this wouldn't disable backface culling so things such as flushing the
clip stack could get confused.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts
2011-09-15 11:25:39 +01:00
committed by Robert Bragg
parent 879ce7301a
commit dbff3a357e
12 changed files with 258 additions and 103 deletions

View File

@ -605,6 +605,58 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
ctx->current_gl_color_mask = color_mask;
}
if (pipelines_difference & COGL_PIPELINE_STATE_CULL_FACE)
{
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_CULL_FACE);
CoglPipelineCullFaceState *cull_face_state
= &authority->big_state->cull_face_state;
if (cull_face_state->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE)
GE( ctx, glDisable (GL_CULL_FACE) );
else
{
CoglFramebuffer *draw_framebuffer = cogl_get_draw_framebuffer ();
gboolean invert_winding;
GE( ctx, glEnable (GL_CULL_FACE) );
switch (cull_face_state->mode)
{
case COGL_PIPELINE_CULL_FACE_MODE_NONE:
g_assert_not_reached ();
case COGL_PIPELINE_CULL_FACE_MODE_FRONT:
GE( ctx, glCullFace (GL_FRONT) );
break;
case COGL_PIPELINE_CULL_FACE_MODE_BACK:
GE( ctx, glCullFace (GL_BACK) );
break;
case COGL_PIPELINE_CULL_FACE_MODE_BOTH:
GE( ctx, glCullFace (GL_FRONT_AND_BACK) );
break;
}
/* If we are painting to an offscreen framebuffer then we
need to invert the winding of the front face because
everything is painted upside down */
invert_winding = cogl_is_offscreen (draw_framebuffer);
switch (cull_face_state->front_winding)
{
case COGL_WINDING_CLOCKWISE:
GE( ctx, glFrontFace (invert_winding ? GL_CCW : GL_CW) );
break;
case COGL_WINDING_COUNTER_CLOCKWISE:
GE( ctx, glFrontFace (invert_winding ? GL_CW : GL_CCW) );
break;
}
}
}
if (pipeline->real_blend_enable != ctx->gl_blend_enable_cache)
{
if (pipeline->real_blend_enable)