mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 01:50:42 -05:00
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:
parent
879ce7301a
commit
dbff3a357e
@ -549,9 +549,6 @@ enable_gl_state (CoglDrawFlags flags,
|
||||
|
||||
_cogl_pipeline_flush_gl_state (source, skip_gl_color, n_tex_coord_attribs);
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
||||
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
|
||||
|
||||
/* Bind the attribute pointers. We need to do this after the
|
||||
@ -726,7 +723,6 @@ enable_gl_state (CoglDrawFlags flags,
|
||||
set_enabled_arrays (&ctx->arrays_enabled, &ctx->temp_bitmask);
|
||||
|
||||
_cogl_enable (enable_flags);
|
||||
_cogl_flush_face_winding ();
|
||||
|
||||
return source;
|
||||
}
|
||||
|
@ -74,8 +74,7 @@ struct _CoglContext
|
||||
/* Enable cache */
|
||||
unsigned long enable_flags;
|
||||
|
||||
gboolean enable_backface_culling;
|
||||
CoglFrontWinding flushed_front_winding;
|
||||
gboolean legacy_backface_culling_enabled;
|
||||
|
||||
/* A few handy matrix constants */
|
||||
CoglMatrix identity_matrix;
|
||||
|
@ -216,8 +216,7 @@ cogl_context_new (CoglDisplay *display,
|
||||
context->current_clip_stack_valid = FALSE;
|
||||
context->current_clip_stack = NULL;
|
||||
|
||||
context->enable_backface_culling = FALSE;
|
||||
context->flushed_front_winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE;
|
||||
context->legacy_backface_culling_enabled = FALSE;
|
||||
|
||||
cogl_matrix_init_identity (&context->identity_matrix);
|
||||
cogl_matrix_init_identity (&context->y_flip_matrix);
|
||||
@ -369,7 +368,6 @@ cogl_context_new (CoglDisplay *display,
|
||||
cogl_push_source (context->opaque_color_pipeline);
|
||||
_cogl_pipeline_flush_gl_state (context->opaque_color_pipeline, FALSE, 0);
|
||||
_cogl_enable (enable_flags);
|
||||
_cogl_flush_face_winding ();
|
||||
|
||||
context->atlases = NULL;
|
||||
g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook));
|
||||
|
@ -106,6 +106,8 @@ COGL_EXT_FUNCTION (void, glFlush,
|
||||
(void))
|
||||
COGL_EXT_FUNCTION (void, glFrontFace,
|
||||
(GLenum mode))
|
||||
COGL_EXT_FUNCTION (void, glCullFace,
|
||||
(GLenum mode))
|
||||
COGL_EXT_FUNCTION (void, glGenTextures,
|
||||
(GLsizei n, GLuint* textures))
|
||||
COGL_EXT_FUNCTION (GLenum, glGetError,
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "cogl-clip-stack.h"
|
||||
#include "cogl-journal-private.h"
|
||||
#include "cogl-winsys-private.h"
|
||||
#include "cogl-pipeline-state-private.h"
|
||||
|
||||
#ifndef GL_FRAMEBUFFER
|
||||
#define GL_FRAMEBUFFER 0x8D40
|
||||
@ -1143,11 +1144,12 @@ notify_buffers_changed (CoglFramebuffer *old_draw_buffer,
|
||||
|
||||
_cogl_clip_stack_dirty ();
|
||||
|
||||
/* If the two draw framebuffers have a different color mask then we
|
||||
need to ensure the logic ops are reflushed the next time
|
||||
if (old_draw_buffer && new_draw_buffer)
|
||||
{
|
||||
/* If the two draw framebuffers have a different color mask then
|
||||
we need to ensure the logic ops are reflushed the next time
|
||||
something is drawn */
|
||||
if (old_draw_buffer && new_draw_buffer &&
|
||||
cogl_framebuffer_get_color_mask (old_draw_buffer) !=
|
||||
if (cogl_framebuffer_get_color_mask (old_draw_buffer) !=
|
||||
cogl_framebuffer_get_color_mask (new_draw_buffer))
|
||||
{
|
||||
ctx->current_pipeline_changes_since_flush |=
|
||||
@ -1155,6 +1157,21 @@ notify_buffers_changed (CoglFramebuffer *old_draw_buffer,
|
||||
ctx->current_pipeline_age--;
|
||||
}
|
||||
|
||||
/* If we're switching from onscreen to offscreen and the last
|
||||
flush pipeline is using backface culling then we also need to
|
||||
reflush the cull face state because the winding order of the
|
||||
front face is flipped for offscreen buffers */
|
||||
if (old_draw_buffer->type != new_draw_buffer->type &&
|
||||
ctx->current_pipeline &&
|
||||
_cogl_pipeline_get_cull_face_mode (ctx->current_pipeline) !=
|
||||
COGL_PIPELINE_CULL_FACE_MODE_NONE)
|
||||
{
|
||||
ctx->current_pipeline_changes_since_flush |=
|
||||
COGL_PIPELINE_STATE_CULL_FACE;
|
||||
ctx->current_pipeline_age--;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX:
|
||||
* To support the deprecated cogl_set_draw_buffer API we keep track
|
||||
* of the last onscreen framebuffer that was set so that it can
|
||||
|
@ -32,12 +32,6 @@
|
||||
#include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COGL_FRONT_WINDING_CLOCKWISE,
|
||||
COGL_FRONT_WINDING_COUNTER_CLOCKWISE
|
||||
} CoglFrontWinding;
|
||||
|
||||
typedef enum {
|
||||
COGL_BOXED_NONE,
|
||||
COGL_BOXED_INT,
|
||||
@ -98,7 +92,6 @@ cogl_gl_error_to_string (GLenum error_code);
|
||||
#define COGL_ENABLE_ALPHA_TEST (1<<1)
|
||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<2)
|
||||
#define COGL_ENABLE_COLOR_ARRAY (1<<3)
|
||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<4)
|
||||
|
||||
int
|
||||
_cogl_get_format_bpp (CoglPixelFormat format);
|
||||
@ -109,9 +102,6 @@ _cogl_enable (unsigned long flags);
|
||||
unsigned long
|
||||
_cogl_get_enable (void);
|
||||
|
||||
void
|
||||
_cogl_flush_face_winding (void);
|
||||
|
||||
void
|
||||
_cogl_transform_point (const CoglMatrix *matrix_mv,
|
||||
const CoglMatrix *matrix_p,
|
||||
|
@ -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)
|
||||
|
@ -429,6 +429,7 @@ typedef enum
|
||||
COGL_PIPELINE_STATE_FOG_INDEX,
|
||||
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS_INDEX,
|
||||
COGL_PIPELINE_STATE_CULL_FACE_INDEX,
|
||||
|
||||
/* non-sparse */
|
||||
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX,
|
||||
@ -474,6 +475,8 @@ typedef enum _CoglPipelineState
|
||||
1L<<COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS =
|
||||
1L<<COGL_PIPELINE_STATE_LOGIC_OPS_INDEX,
|
||||
COGL_PIPELINE_STATE_CULL_FACE =
|
||||
1L<<COGL_PIPELINE_STATE_CULL_FACE_INDEX,
|
||||
|
||||
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE =
|
||||
1L<<COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX,
|
||||
@ -508,7 +511,8 @@ typedef enum _CoglPipelineState
|
||||
COGL_PIPELINE_STATE_DEPTH | \
|
||||
COGL_PIPELINE_STATE_FOG | \
|
||||
COGL_PIPELINE_STATE_POINT_SIZE | \
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS)
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS | \
|
||||
COGL_PIPELINE_STATE_CULL_FACE)
|
||||
|
||||
#define COGL_PIPELINE_STATE_MULTI_PROPERTY \
|
||||
(COGL_PIPELINE_STATE_LAYERS | \
|
||||
@ -516,7 +520,8 @@ typedef enum _CoglPipelineState
|
||||
COGL_PIPELINE_STATE_BLEND | \
|
||||
COGL_PIPELINE_STATE_DEPTH | \
|
||||
COGL_PIPELINE_STATE_FOG | \
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS)
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS | \
|
||||
COGL_PIPELINE_STATE_CULL_FACE)
|
||||
|
||||
#define COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN \
|
||||
(COGL_PIPELINE_STATE_LAYERS | \
|
||||
@ -557,6 +562,20 @@ typedef enum _CoglPipelineBlendEnable
|
||||
COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC
|
||||
} CoglPipelineBlendEnable;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COGL_PIPELINE_CULL_FACE_MODE_NONE,
|
||||
COGL_PIPELINE_CULL_FACE_MODE_FRONT,
|
||||
COGL_PIPELINE_CULL_FACE_MODE_BACK,
|
||||
COGL_PIPELINE_CULL_FACE_MODE_BOTH
|
||||
} CoglPipelineCullFaceMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COGL_WINDING_CLOCKWISE,
|
||||
COGL_WINDING_COUNTER_CLOCKWISE
|
||||
} CoglWinding;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Determines how this pipeline is blended with other primitives */
|
||||
@ -586,6 +605,12 @@ typedef struct
|
||||
CoglColorMask color_mask;
|
||||
} CoglPipelineLogicOpsState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglPipelineCullFaceMode mode;
|
||||
CoglWinding front_winding;
|
||||
} CoglPipelineCullFaceState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglPipelineLightingState lighting_state;
|
||||
@ -596,6 +621,7 @@ typedef struct
|
||||
CoglPipelineFogState fog_state;
|
||||
float point_size;
|
||||
CoglPipelineLogicOpsState logic_ops_state;
|
||||
CoglPipelineCullFaceState cull_face_state;
|
||||
} CoglPipelineBigState;
|
||||
|
||||
typedef enum
|
||||
|
@ -35,6 +35,14 @@ void
|
||||
_cogl_pipeline_set_fog_state (CoglPipeline *pipeline,
|
||||
const CoglPipelineFogState *fog_state);
|
||||
|
||||
void
|
||||
_cogl_pipeline_set_cull_face_state (CoglPipeline *pipeline,
|
||||
const CoglPipelineCullFaceState *
|
||||
cull_face_state);
|
||||
|
||||
CoglPipelineCullFaceMode
|
||||
_cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline);
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_color_equal (CoglPipeline *authority0,
|
||||
CoglPipeline *authority1);
|
||||
@ -75,6 +83,10 @@ gboolean
|
||||
_cogl_pipeline_user_shader_equal (CoglPipeline *authority0,
|
||||
CoglPipeline *authority1);
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0,
|
||||
CoglPipeline *authority1);
|
||||
|
||||
void
|
||||
_cogl_pipeline_hash_color_state (CoglPipeline *authority,
|
||||
CoglPipelineHashState *state);
|
||||
@ -123,4 +135,8 @@ void
|
||||
_cogl_pipeline_hash_logic_ops_state (CoglPipeline *authority,
|
||||
CoglPipelineHashState *state);
|
||||
|
||||
void
|
||||
_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority,
|
||||
CoglPipelineHashState *state);
|
||||
|
||||
#endif /* __COGL_PIPELINE_STATE_PRIVATE_H */
|
||||
|
@ -209,6 +209,27 @@ _cogl_pipeline_logic_ops_state_equal (CoglPipeline *authority0,
|
||||
return logic_ops_state0->color_mask == logic_ops_state1->color_mask;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0,
|
||||
CoglPipeline *authority1)
|
||||
{
|
||||
CoglPipelineCullFaceState *cull_face_state0
|
||||
= &authority0->big_state->cull_face_state;
|
||||
CoglPipelineCullFaceState *cull_face_state1
|
||||
= &authority1->big_state->cull_face_state;
|
||||
|
||||
/* The cull face state is considered equal if two pipelines are both
|
||||
set to no culling. If the front winding property is ever used for
|
||||
anything else or the comparison is used not just for drawing then
|
||||
this would have to change */
|
||||
|
||||
if (cull_face_state0->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE)
|
||||
return cull_face_state1->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE;
|
||||
|
||||
return (cull_face_state0->mode == cull_face_state1->mode &&
|
||||
cull_face_state0->front_winding == cull_face_state1->front_winding);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_user_shader_equal (CoglPipeline *authority0,
|
||||
CoglPipeline *authority1)
|
||||
@ -1155,6 +1176,52 @@ _cogl_pipeline_set_fog_state (CoglPipeline *pipeline,
|
||||
_cogl_pipeline_fog_state_equal);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_pipeline_set_cull_face_state (CoglPipeline *pipeline,
|
||||
const CoglPipelineCullFaceState *
|
||||
cull_face_state)
|
||||
{
|
||||
CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
|
||||
CoglPipeline *authority;
|
||||
CoglPipelineCullFaceState *current_cull_face_state;
|
||||
|
||||
g_return_if_fail (cogl_is_pipeline (pipeline));
|
||||
|
||||
authority = _cogl_pipeline_get_authority (pipeline, state);
|
||||
|
||||
current_cull_face_state = &authority->big_state->cull_face_state;
|
||||
|
||||
if (current_cull_face_state->mode == cull_face_state->mode &&
|
||||
current_cull_face_state->front_winding == cull_face_state->front_winding)
|
||||
return;
|
||||
|
||||
/* - Flush journal primitives referencing the current state.
|
||||
* - Make sure the pipeline has no dependants so it may be modified.
|
||||
* - If the pipeline isn't currently an authority for the state being
|
||||
* changed, then initialize that state from the current authority.
|
||||
*/
|
||||
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
|
||||
|
||||
pipeline->big_state->cull_face_state = *cull_face_state;
|
||||
|
||||
_cogl_pipeline_update_authority (pipeline, authority, state,
|
||||
_cogl_pipeline_cull_face_state_equal);
|
||||
}
|
||||
|
||||
CoglPipelineCullFaceMode
|
||||
_cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline)
|
||||
{
|
||||
CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
|
||||
CoglPipeline *authority;
|
||||
|
||||
g_return_val_if_fail (cogl_is_pipeline (pipeline),
|
||||
COGL_PIPELINE_CULL_FACE_MODE_NONE);
|
||||
|
||||
authority = _cogl_pipeline_get_authority (pipeline, state);
|
||||
|
||||
return authority->big_state->cull_face_state.mode;
|
||||
}
|
||||
|
||||
float
|
||||
cogl_pipeline_get_point_size (CoglPipeline *pipeline)
|
||||
{
|
||||
@ -1365,3 +1432,26 @@ _cogl_pipeline_hash_logic_ops_state (CoglPipeline *authority,
|
||||
state->hash = _cogl_util_one_at_a_time_hash (state->hash, &logic_ops_state->color_mask,
|
||||
sizeof (CoglColorMask));
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority,
|
||||
CoglPipelineHashState *state)
|
||||
{
|
||||
CoglPipelineCullFaceState *cull_face_state
|
||||
= &authority->big_state->cull_face_state;
|
||||
|
||||
/* The cull face state is considered equal if two pipelines are both
|
||||
set to no culling. If the front winding property is ever used for
|
||||
anything else or the hashing is used not just for drawing then
|
||||
this would have to change */
|
||||
if (cull_face_state->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE)
|
||||
state->hash =
|
||||
_cogl_util_one_at_a_time_hash (state->hash,
|
||||
&cull_face_state->mode,
|
||||
sizeof (CoglPipelineCullFaceMode));
|
||||
else
|
||||
state->hash =
|
||||
_cogl_util_one_at_a_time_hash (state->hash,
|
||||
cull_face_state,
|
||||
sizeof (CoglPipelineCullFaceState));
|
||||
}
|
||||
|
@ -190,6 +190,7 @@ _cogl_pipeline_init_default_pipeline (void)
|
||||
CoglPipelineBlendState *blend_state = &big_state->blend_state;
|
||||
CoglDepthState *depth_state = &big_state->depth_state;
|
||||
CoglPipelineLogicOpsState *logic_ops_state = &big_state->logic_ops_state;
|
||||
CoglPipelineCullFaceState *cull_face_state = &big_state->cull_face_state;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -297,6 +298,9 @@ _cogl_pipeline_init_default_pipeline (void)
|
||||
|
||||
logic_ops_state->color_mask = COGL_COLOR_MASK_ALL;
|
||||
|
||||
cull_face_state->mode = COGL_PIPELINE_CULL_FACE_MODE_NONE;
|
||||
cull_face_state->front_winding = COGL_WINDING_COUNTER_CLOCKWISE;
|
||||
|
||||
ctx->default_pipeline = _cogl_pipeline_object_new (pipeline);
|
||||
}
|
||||
|
||||
@ -1047,6 +1051,13 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
|
||||
sizeof (CoglPipelineLogicOpsState));
|
||||
}
|
||||
|
||||
if (differences & COGL_PIPELINE_STATE_CULL_FACE)
|
||||
{
|
||||
memcpy (&big_state->cull_face_state,
|
||||
&src->big_state->cull_face_state,
|
||||
sizeof (CoglPipelineCullFaceState));
|
||||
}
|
||||
|
||||
/* XXX: we shouldn't bother doing this in most cases since
|
||||
* _copy_differences is typically used to initialize pipeline state
|
||||
* by copying it from the current authority, so it's not actually
|
||||
@ -1124,6 +1135,13 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline,
|
||||
sizeof (CoglPipelineLogicOpsState));
|
||||
break;
|
||||
}
|
||||
case COGL_PIPELINE_STATE_CULL_FACE:
|
||||
{
|
||||
memcpy (&pipeline->big_state->cull_face_state,
|
||||
&authority->big_state->cull_face_state,
|
||||
sizeof (CoglPipelineCullFaceState));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2752,6 +2770,12 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||
_cogl_pipeline_fog_state_equal))
|
||||
goto done;
|
||||
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_CULL_FACE_INDEX,
|
||||
_cogl_pipeline_cull_face_state_equal))
|
||||
goto done;
|
||||
|
||||
if (!simple_property_equal (authorities0, authorities1,
|
||||
pipelines_difference,
|
||||
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||
@ -3208,6 +3232,14 @@ _cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline)
|
||||
|
||||
if (ctx->legacy_fog_state.enabled)
|
||||
_cogl_pipeline_set_fog_state (pipeline, &ctx->legacy_fog_state);
|
||||
|
||||
if (ctx->legacy_backface_culling_enabled)
|
||||
{
|
||||
CoglPipelineCullFaceState state;
|
||||
state.mode = COGL_PIPELINE_CULL_FACE_MODE_BACK;
|
||||
state.front_winding = COGL_WINDING_COUNTER_CLOCKWISE;
|
||||
_cogl_pipeline_set_cull_face_state (pipeline, &state);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -3346,13 +3378,15 @@ _cogl_pipeline_init_state_hash_functions (void)
|
||||
_cogl_pipeline_hash_depth_state;
|
||||
state_hash_functions[COGL_PIPELINE_STATE_FOG_INDEX] =
|
||||
_cogl_pipeline_hash_fog_state;
|
||||
state_hash_functions[COGL_PIPELINE_STATE_CULL_FACE_INDEX] =
|
||||
_cogl_pipeline_hash_cull_face_state;
|
||||
state_hash_functions[COGL_PIPELINE_STATE_POINT_SIZE_INDEX] =
|
||||
_cogl_pipeline_hash_point_size_state;
|
||||
state_hash_functions[COGL_PIPELINE_STATE_LOGIC_OPS_INDEX] =
|
||||
_cogl_pipeline_hash_logic_ops_state;
|
||||
|
||||
/* So we get a big error if we forget to update this code! */
|
||||
g_assert (COGL_PIPELINE_STATE_SPARSE_COUNT == 12);
|
||||
g_assert (COGL_PIPELINE_STATE_SPARSE_COUNT == 13);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
|
79
cogl/cogl.c
79
cogl/cogl.c
@ -141,33 +141,6 @@ cogl_clear (const CoglColor *color, unsigned long buffers)
|
||||
cogl_framebuffer_clear (cogl_get_draw_framebuffer (), buffers, color);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
toggle_flag (CoglContext *ctx,
|
||||
unsigned long new_flags,
|
||||
unsigned long flag,
|
||||
GLenum gl_flag)
|
||||
{
|
||||
/* Toggles and caches a single enable flag on or off
|
||||
* by comparing to current state
|
||||
*/
|
||||
if (new_flags & flag)
|
||||
{
|
||||
if (!(ctx->enable_flags & flag))
|
||||
{
|
||||
GE( ctx, glEnable (gl_flag) );
|
||||
ctx->enable_flags |= flag;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (ctx->enable_flags & flag)
|
||||
{
|
||||
GE( ctx, glDisable (gl_flag) );
|
||||
ctx->enable_flags &= ~flag;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
|
||||
|
||||
static gboolean
|
||||
@ -209,10 +182,6 @@ _cogl_enable (unsigned long flags)
|
||||
*/
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_BACKFACE_CULLING,
|
||||
GL_CULL_FACE);
|
||||
|
||||
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
|
||||
if (ctx->driver != COGL_DRIVER_GLES2)
|
||||
{
|
||||
@ -264,13 +233,15 @@ cogl_set_backface_culling_enabled (gboolean setting)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (ctx->enable_backface_culling == setting)
|
||||
if (ctx->legacy_backface_culling_enabled == setting)
|
||||
return;
|
||||
|
||||
/* Currently the journal can't track changes to backface culling state... */
|
||||
_cogl_framebuffer_flush_journal (cogl_get_draw_framebuffer ());
|
||||
ctx->legacy_backface_culling_enabled = setting;
|
||||
|
||||
ctx->enable_backface_culling = setting;
|
||||
if (ctx->legacy_backface_culling_enabled)
|
||||
ctx->legacy_state_set++;
|
||||
else
|
||||
ctx->legacy_state_set--;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -278,39 +249,7 @@ cogl_get_backface_culling_enabled (void)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, FALSE);
|
||||
|
||||
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_framebuffer ()))
|
||||
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 (ctx, glFrontFace (GL_CW));
|
||||
else
|
||||
GE (ctx, glFrontFace (GL_CCW));
|
||||
ctx->flushed_front_winding = winding;
|
||||
}
|
||||
return ctx->legacy_backface_culling_enabled;
|
||||
}
|
||||
|
||||
void
|
||||
@ -726,11 +665,7 @@ cogl_begin_gl (void)
|
||||
FALSE,
|
||||
cogl_pipeline_get_n_layers (pipeline));
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
||||
_cogl_enable (enable_flags);
|
||||
_cogl_flush_face_winding ();
|
||||
|
||||
/* Disable any cached vertex arrays */
|
||||
_cogl_attribute_disable_cached_arrays ();
|
||||
|
Loading…
Reference in New Issue
Block a user