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);
|
_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);
|
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
|
||||||
|
|
||||||
/* Bind the attribute pointers. We need to do this after the
|
/* 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);
|
set_enabled_arrays (&ctx->arrays_enabled, &ctx->temp_bitmask);
|
||||||
|
|
||||||
_cogl_enable (enable_flags);
|
_cogl_enable (enable_flags);
|
||||||
_cogl_flush_face_winding ();
|
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
@ -74,8 +74,7 @@ struct _CoglContext
|
|||||||
/* Enable cache */
|
/* Enable cache */
|
||||||
unsigned long enable_flags;
|
unsigned long enable_flags;
|
||||||
|
|
||||||
gboolean enable_backface_culling;
|
gboolean legacy_backface_culling_enabled;
|
||||||
CoglFrontWinding flushed_front_winding;
|
|
||||||
|
|
||||||
/* A few handy matrix constants */
|
/* A few handy matrix constants */
|
||||||
CoglMatrix identity_matrix;
|
CoglMatrix identity_matrix;
|
||||||
|
@ -216,8 +216,7 @@ cogl_context_new (CoglDisplay *display,
|
|||||||
context->current_clip_stack_valid = FALSE;
|
context->current_clip_stack_valid = FALSE;
|
||||||
context->current_clip_stack = NULL;
|
context->current_clip_stack = NULL;
|
||||||
|
|
||||||
context->enable_backface_culling = FALSE;
|
context->legacy_backface_culling_enabled = FALSE;
|
||||||
context->flushed_front_winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE;
|
|
||||||
|
|
||||||
cogl_matrix_init_identity (&context->identity_matrix);
|
cogl_matrix_init_identity (&context->identity_matrix);
|
||||||
cogl_matrix_init_identity (&context->y_flip_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_push_source (context->opaque_color_pipeline);
|
||||||
_cogl_pipeline_flush_gl_state (context->opaque_color_pipeline, FALSE, 0);
|
_cogl_pipeline_flush_gl_state (context->opaque_color_pipeline, FALSE, 0);
|
||||||
_cogl_enable (enable_flags);
|
_cogl_enable (enable_flags);
|
||||||
_cogl_flush_face_winding ();
|
|
||||||
|
|
||||||
context->atlases = NULL;
|
context->atlases = NULL;
|
||||||
g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook));
|
g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook));
|
||||||
|
@ -106,6 +106,8 @@ COGL_EXT_FUNCTION (void, glFlush,
|
|||||||
(void))
|
(void))
|
||||||
COGL_EXT_FUNCTION (void, glFrontFace,
|
COGL_EXT_FUNCTION (void, glFrontFace,
|
||||||
(GLenum mode))
|
(GLenum mode))
|
||||||
|
COGL_EXT_FUNCTION (void, glCullFace,
|
||||||
|
(GLenum mode))
|
||||||
COGL_EXT_FUNCTION (void, glGenTextures,
|
COGL_EXT_FUNCTION (void, glGenTextures,
|
||||||
(GLsizei n, GLuint* textures))
|
(GLsizei n, GLuint* textures))
|
||||||
COGL_EXT_FUNCTION (GLenum, glGetError,
|
COGL_EXT_FUNCTION (GLenum, glGetError,
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "cogl-clip-stack.h"
|
#include "cogl-clip-stack.h"
|
||||||
#include "cogl-journal-private.h"
|
#include "cogl-journal-private.h"
|
||||||
#include "cogl-winsys-private.h"
|
#include "cogl-winsys-private.h"
|
||||||
|
#include "cogl-pipeline-state-private.h"
|
||||||
|
|
||||||
#ifndef GL_FRAMEBUFFER
|
#ifndef GL_FRAMEBUFFER
|
||||||
#define GL_FRAMEBUFFER 0x8D40
|
#define GL_FRAMEBUFFER 0x8D40
|
||||||
@ -1143,16 +1144,32 @@ notify_buffers_changed (CoglFramebuffer *old_draw_buffer,
|
|||||||
|
|
||||||
_cogl_clip_stack_dirty ();
|
_cogl_clip_stack_dirty ();
|
||||||
|
|
||||||
/* If the two draw framebuffers have a different color mask then we
|
if (old_draw_buffer && new_draw_buffer)
|
||||||
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) !=
|
|
||||||
cogl_framebuffer_get_color_mask (new_draw_buffer))
|
|
||||||
{
|
{
|
||||||
ctx->current_pipeline_changes_since_flush |=
|
/* If the two draw framebuffers have a different color mask then
|
||||||
COGL_PIPELINE_STATE_LOGIC_OPS;
|
we need to ensure the logic ops are reflushed the next time
|
||||||
ctx->current_pipeline_age--;
|
something is drawn */
|
||||||
|
if (cogl_framebuffer_get_color_mask (old_draw_buffer) !=
|
||||||
|
cogl_framebuffer_get_color_mask (new_draw_buffer))
|
||||||
|
{
|
||||||
|
ctx->current_pipeline_changes_since_flush |=
|
||||||
|
COGL_PIPELINE_STATE_LOGIC_OPS;
|
||||||
|
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:
|
/* XXX:
|
||||||
|
@ -32,12 +32,6 @@
|
|||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
COGL_FRONT_WINDING_CLOCKWISE,
|
|
||||||
COGL_FRONT_WINDING_COUNTER_CLOCKWISE
|
|
||||||
} CoglFrontWinding;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
COGL_BOXED_NONE,
|
COGL_BOXED_NONE,
|
||||||
COGL_BOXED_INT,
|
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_ALPHA_TEST (1<<1)
|
||||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<2)
|
#define COGL_ENABLE_VERTEX_ARRAY (1<<2)
|
||||||
#define COGL_ENABLE_COLOR_ARRAY (1<<3)
|
#define COGL_ENABLE_COLOR_ARRAY (1<<3)
|
||||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<4)
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_cogl_get_format_bpp (CoglPixelFormat format);
|
_cogl_get_format_bpp (CoglPixelFormat format);
|
||||||
@ -109,9 +102,6 @@ _cogl_enable (unsigned long flags);
|
|||||||
unsigned long
|
unsigned long
|
||||||
_cogl_get_enable (void);
|
_cogl_get_enable (void);
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_flush_face_winding (void);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_transform_point (const CoglMatrix *matrix_mv,
|
_cogl_transform_point (const CoglMatrix *matrix_mv,
|
||||||
const CoglMatrix *matrix_p,
|
const CoglMatrix *matrix_p,
|
||||||
|
@ -605,6 +605,58 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
|
|||||||
ctx->current_gl_color_mask = color_mask;
|
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 != ctx->gl_blend_enable_cache)
|
||||||
{
|
{
|
||||||
if (pipeline->real_blend_enable)
|
if (pipeline->real_blend_enable)
|
||||||
|
@ -429,6 +429,7 @@ typedef enum
|
|||||||
COGL_PIPELINE_STATE_FOG_INDEX,
|
COGL_PIPELINE_STATE_FOG_INDEX,
|
||||||
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||||
COGL_PIPELINE_STATE_LOGIC_OPS_INDEX,
|
COGL_PIPELINE_STATE_LOGIC_OPS_INDEX,
|
||||||
|
COGL_PIPELINE_STATE_CULL_FACE_INDEX,
|
||||||
|
|
||||||
/* non-sparse */
|
/* non-sparse */
|
||||||
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX,
|
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX,
|
||||||
@ -474,6 +475,8 @@ typedef enum _CoglPipelineState
|
|||||||
1L<<COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
1L<<COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||||
COGL_PIPELINE_STATE_LOGIC_OPS =
|
COGL_PIPELINE_STATE_LOGIC_OPS =
|
||||||
1L<<COGL_PIPELINE_STATE_LOGIC_OPS_INDEX,
|
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 =
|
COGL_PIPELINE_STATE_REAL_BLEND_ENABLE =
|
||||||
1L<<COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX,
|
1L<<COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX,
|
||||||
@ -508,7 +511,8 @@ typedef enum _CoglPipelineState
|
|||||||
COGL_PIPELINE_STATE_DEPTH | \
|
COGL_PIPELINE_STATE_DEPTH | \
|
||||||
COGL_PIPELINE_STATE_FOG | \
|
COGL_PIPELINE_STATE_FOG | \
|
||||||
COGL_PIPELINE_STATE_POINT_SIZE | \
|
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 \
|
#define COGL_PIPELINE_STATE_MULTI_PROPERTY \
|
||||||
(COGL_PIPELINE_STATE_LAYERS | \
|
(COGL_PIPELINE_STATE_LAYERS | \
|
||||||
@ -516,7 +520,8 @@ typedef enum _CoglPipelineState
|
|||||||
COGL_PIPELINE_STATE_BLEND | \
|
COGL_PIPELINE_STATE_BLEND | \
|
||||||
COGL_PIPELINE_STATE_DEPTH | \
|
COGL_PIPELINE_STATE_DEPTH | \
|
||||||
COGL_PIPELINE_STATE_FOG | \
|
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 \
|
#define COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN \
|
||||||
(COGL_PIPELINE_STATE_LAYERS | \
|
(COGL_PIPELINE_STATE_LAYERS | \
|
||||||
@ -557,6 +562,20 @@ typedef enum _CoglPipelineBlendEnable
|
|||||||
COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC
|
COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC
|
||||||
} CoglPipelineBlendEnable;
|
} 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
|
typedef struct
|
||||||
{
|
{
|
||||||
/* Determines how this pipeline is blended with other primitives */
|
/* Determines how this pipeline is blended with other primitives */
|
||||||
@ -586,6 +605,12 @@ typedef struct
|
|||||||
CoglColorMask color_mask;
|
CoglColorMask color_mask;
|
||||||
} CoglPipelineLogicOpsState;
|
} CoglPipelineLogicOpsState;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CoglPipelineCullFaceMode mode;
|
||||||
|
CoglWinding front_winding;
|
||||||
|
} CoglPipelineCullFaceState;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CoglPipelineLightingState lighting_state;
|
CoglPipelineLightingState lighting_state;
|
||||||
@ -596,6 +621,7 @@ typedef struct
|
|||||||
CoglPipelineFogState fog_state;
|
CoglPipelineFogState fog_state;
|
||||||
float point_size;
|
float point_size;
|
||||||
CoglPipelineLogicOpsState logic_ops_state;
|
CoglPipelineLogicOpsState logic_ops_state;
|
||||||
|
CoglPipelineCullFaceState cull_face_state;
|
||||||
} CoglPipelineBigState;
|
} CoglPipelineBigState;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -35,6 +35,14 @@ void
|
|||||||
_cogl_pipeline_set_fog_state (CoglPipeline *pipeline,
|
_cogl_pipeline_set_fog_state (CoglPipeline *pipeline,
|
||||||
const CoglPipelineFogState *fog_state);
|
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
|
gboolean
|
||||||
_cogl_pipeline_color_equal (CoglPipeline *authority0,
|
_cogl_pipeline_color_equal (CoglPipeline *authority0,
|
||||||
CoglPipeline *authority1);
|
CoglPipeline *authority1);
|
||||||
@ -75,6 +83,10 @@ gboolean
|
|||||||
_cogl_pipeline_user_shader_equal (CoglPipeline *authority0,
|
_cogl_pipeline_user_shader_equal (CoglPipeline *authority0,
|
||||||
CoglPipeline *authority1);
|
CoglPipeline *authority1);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0,
|
||||||
|
CoglPipeline *authority1);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_pipeline_hash_color_state (CoglPipeline *authority,
|
_cogl_pipeline_hash_color_state (CoglPipeline *authority,
|
||||||
CoglPipelineHashState *state);
|
CoglPipelineHashState *state);
|
||||||
@ -123,4 +135,8 @@ void
|
|||||||
_cogl_pipeline_hash_logic_ops_state (CoglPipeline *authority,
|
_cogl_pipeline_hash_logic_ops_state (CoglPipeline *authority,
|
||||||
CoglPipelineHashState *state);
|
CoglPipelineHashState *state);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority,
|
||||||
|
CoglPipelineHashState *state);
|
||||||
|
|
||||||
#endif /* __COGL_PIPELINE_STATE_PRIVATE_H */
|
#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;
|
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
|
gboolean
|
||||||
_cogl_pipeline_user_shader_equal (CoglPipeline *authority0,
|
_cogl_pipeline_user_shader_equal (CoglPipeline *authority0,
|
||||||
CoglPipeline *authority1)
|
CoglPipeline *authority1)
|
||||||
@ -1155,6 +1176,52 @@ _cogl_pipeline_set_fog_state (CoglPipeline *pipeline,
|
|||||||
_cogl_pipeline_fog_state_equal);
|
_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
|
float
|
||||||
cogl_pipeline_get_point_size (CoglPipeline *pipeline)
|
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,
|
state->hash = _cogl_util_one_at_a_time_hash (state->hash, &logic_ops_state->color_mask,
|
||||||
sizeof (CoglColorMask));
|
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;
|
CoglPipelineBlendState *blend_state = &big_state->blend_state;
|
||||||
CoglDepthState *depth_state = &big_state->depth_state;
|
CoglDepthState *depth_state = &big_state->depth_state;
|
||||||
CoglPipelineLogicOpsState *logic_ops_state = &big_state->logic_ops_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);
|
_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;
|
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);
|
ctx->default_pipeline = _cogl_pipeline_object_new (pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1047,6 +1051,13 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
|
|||||||
sizeof (CoglPipelineLogicOpsState));
|
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
|
/* XXX: we shouldn't bother doing this in most cases since
|
||||||
* _copy_differences is typically used to initialize pipeline state
|
* _copy_differences is typically used to initialize pipeline state
|
||||||
* by copying it from the current authority, so it's not actually
|
* 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));
|
sizeof (CoglPipelineLogicOpsState));
|
||||||
break;
|
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))
|
_cogl_pipeline_fog_state_equal))
|
||||||
goto done;
|
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,
|
if (!simple_property_equal (authorities0, authorities1,
|
||||||
pipelines_difference,
|
pipelines_difference,
|
||||||
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||||
@ -3208,6 +3232,14 @@ _cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline)
|
|||||||
|
|
||||||
if (ctx->legacy_fog_state.enabled)
|
if (ctx->legacy_fog_state.enabled)
|
||||||
_cogl_pipeline_set_fog_state (pipeline, &ctx->legacy_fog_state);
|
_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
|
void
|
||||||
@ -3346,13 +3378,15 @@ _cogl_pipeline_init_state_hash_functions (void)
|
|||||||
_cogl_pipeline_hash_depth_state;
|
_cogl_pipeline_hash_depth_state;
|
||||||
state_hash_functions[COGL_PIPELINE_STATE_FOG_INDEX] =
|
state_hash_functions[COGL_PIPELINE_STATE_FOG_INDEX] =
|
||||||
_cogl_pipeline_hash_fog_state;
|
_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] =
|
state_hash_functions[COGL_PIPELINE_STATE_POINT_SIZE_INDEX] =
|
||||||
_cogl_pipeline_hash_point_size_state;
|
_cogl_pipeline_hash_point_size_state;
|
||||||
state_hash_functions[COGL_PIPELINE_STATE_LOGIC_OPS_INDEX] =
|
state_hash_functions[COGL_PIPELINE_STATE_LOGIC_OPS_INDEX] =
|
||||||
_cogl_pipeline_hash_logic_ops_state;
|
_cogl_pipeline_hash_logic_ops_state;
|
||||||
|
|
||||||
/* So we get a big error if we forget to update this code! */
|
/* 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
|
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);
|
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)
|
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -209,10 +182,6 @@ _cogl_enable (unsigned long flags)
|
|||||||
*/
|
*/
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_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 defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
|
||||||
if (ctx->driver != COGL_DRIVER_GLES2)
|
if (ctx->driver != COGL_DRIVER_GLES2)
|
||||||
{
|
{
|
||||||
@ -264,13 +233,15 @@ cogl_set_backface_culling_enabled (gboolean setting)
|
|||||||
{
|
{
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
if (ctx->enable_backface_culling == setting)
|
if (ctx->legacy_backface_culling_enabled == setting)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Currently the journal can't track changes to backface culling state... */
|
ctx->legacy_backface_culling_enabled = setting;
|
||||||
_cogl_framebuffer_flush_journal (cogl_get_draw_framebuffer ());
|
|
||||||
|
|
||||||
ctx->enable_backface_culling = setting;
|
if (ctx->legacy_backface_culling_enabled)
|
||||||
|
ctx->legacy_state_set++;
|
||||||
|
else
|
||||||
|
ctx->legacy_state_set--;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -278,39 +249,7 @@ cogl_get_backface_culling_enabled (void)
|
|||||||
{
|
{
|
||||||
_COGL_GET_CONTEXT (ctx, FALSE);
|
_COGL_GET_CONTEXT (ctx, FALSE);
|
||||||
|
|
||||||
return ctx->enable_backface_culling;
|
return ctx->legacy_backface_culling_enabled;
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -726,11 +665,7 @@ cogl_begin_gl (void)
|
|||||||
FALSE,
|
FALSE,
|
||||||
cogl_pipeline_get_n_layers (pipeline));
|
cogl_pipeline_get_n_layers (pipeline));
|
||||||
|
|
||||||
if (ctx->enable_backface_culling)
|
|
||||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
|
||||||
|
|
||||||
_cogl_enable (enable_flags);
|
_cogl_enable (enable_flags);
|
||||||
_cogl_flush_face_winding ();
|
|
||||||
|
|
||||||
/* Disable any cached vertex arrays */
|
/* Disable any cached vertex arrays */
|
||||||
_cogl_attribute_disable_cached_arrays ();
|
_cogl_attribute_disable_cached_arrays ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user