pipeline: Make the backface culling experimental public

This adds two new experimental public functions to replace the old
internal _cogl_pipeline_set_cull_face_state function:

void
cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline,
                                  CoglPipelineCullFaceMode cull_face_mode);

void
cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline,
                                      CoglWinding front_winding);

There are also the corresponding getters.

https://bugzilla.gnome.org/show_bug.cgi?id=663628

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2011-11-08 13:58:33 +00:00
parent 8be44f9876
commit 5369b3c601
8 changed files with 165 additions and 38 deletions

View File

@ -1132,7 +1132,7 @@ notify_buffers_changed (CoglFramebuffer *old_draw_buffer,
front face is flipped for offscreen buffers */ front face is flipped for offscreen buffers */
if (old_draw_buffer->type != new_draw_buffer->type && if (old_draw_buffer->type != new_draw_buffer->type &&
ctx->current_pipeline && ctx->current_pipeline &&
_cogl_pipeline_get_cull_face_mode (ctx->current_pipeline) != cogl_pipeline_get_cull_face_mode (ctx->current_pipeline) !=
COGL_PIPELINE_CULL_FACE_MODE_NONE) COGL_PIPELINE_CULL_FACE_MODE_NONE)
{ {
ctx->current_pipeline_changes_since_flush |= ctx->current_pipeline_changes_since_flush |=

View File

@ -298,20 +298,6 @@ 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 */

View File

@ -35,14 +35,6 @@ 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);

View File

@ -1177,22 +1177,20 @@ _cogl_pipeline_set_fog_state (CoglPipeline *pipeline,
} }
void void
_cogl_pipeline_set_cull_face_state (CoglPipeline *pipeline, cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline,
const CoglPipelineCullFaceState * CoglPipelineCullFaceMode cull_face_mode)
cull_face_state)
{ {
CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
CoglPipeline *authority; CoglPipeline *authority;
CoglPipelineCullFaceState *current_cull_face_state; CoglPipelineCullFaceState *cull_face_state;
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
authority = _cogl_pipeline_get_authority (pipeline, state); authority = _cogl_pipeline_get_authority (pipeline, state);
current_cull_face_state = &authority->big_state->cull_face_state; cull_face_state = &authority->big_state->cull_face_state;
if (current_cull_face_state->mode == cull_face_state->mode && if (cull_face_state->mode == cull_face_mode)
current_cull_face_state->front_winding == cull_face_state->front_winding)
return; return;
/* - Flush journal primitives referencing the current state. /* - Flush journal primitives referencing the current state.
@ -1202,14 +1200,44 @@ _cogl_pipeline_set_cull_face_state (CoglPipeline *pipeline,
*/ */
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
pipeline->big_state->cull_face_state = *cull_face_state; pipeline->big_state->cull_face_state.mode = cull_face_mode;
_cogl_pipeline_update_authority (pipeline, authority, state,
_cogl_pipeline_cull_face_state_equal);
}
void
cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline,
CoglWinding front_winding)
{
CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
CoglPipeline *authority;
CoglPipelineCullFaceState *cull_face_state;
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
authority = _cogl_pipeline_get_authority (pipeline, state);
cull_face_state = &authority->big_state->cull_face_state;
if (cull_face_state->front_winding == 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.front_winding = front_winding;
_cogl_pipeline_update_authority (pipeline, authority, state, _cogl_pipeline_update_authority (pipeline, authority, state,
_cogl_pipeline_cull_face_state_equal); _cogl_pipeline_cull_face_state_equal);
} }
CoglPipelineCullFaceMode CoglPipelineCullFaceMode
_cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline) cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline)
{ {
CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
CoglPipeline *authority; CoglPipeline *authority;
@ -1222,6 +1250,20 @@ _cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline)
return authority->big_state->cull_face_state.mode; return authority->big_state->cull_face_state.mode;
} }
CoglWinding
cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline)
{
CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
CoglPipeline *authority;
_COGL_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.front_winding;
}
float float
cogl_pipeline_get_point_size (CoglPipeline *pipeline) cogl_pipeline_get_point_size (CoglPipeline *pipeline)
{ {

View File

@ -686,6 +686,97 @@ void
cogl_pipeline_get_depth_state (CoglPipeline *pipeline, cogl_pipeline_get_depth_state (CoglPipeline *pipeline,
CoglDepthState *state_out); CoglDepthState *state_out);
/**
* CoglPipelineCullFaceMode:
* @COGL_PIPELINE_CULL_FACE_MODE_NONE: Neither face will be
* called. This is the default.
* @COGL_PIPELINE_CULL_FACE_MODE_FRONT: Front faces will be called.
* @COGL_PIPELINE_CULL_FACE_MODE_BACK: Back faces will be called.
* @COGL_PIPELINE_CULL_FACE_MODE_BOTH: All faces will be called.
*
* Specifies which faces should be called. This can be set on a
* pipeline using cogl_pipeline_set_cull_face_mode().
*/
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;
/**
* cogl_pipeline_set_cull_face_mode:
* @pipeline: A #CoglPipeline
* @cull_face_mode: The new mode to set
*
* Sets which faces will be culled when drawing. Face culling can be
* used to increase efficiency by avoiding drawing faces that would
* get overridden. For example, if a model has gaps so that it is
* impossible to see the inside then faces which are facing away from
* the screen will never be seen so there is no point in drawing
* them. This can be acheived by setting the cull face mode to
* %COGL_PIPELINE_CULL_FACE_MODE_BACK.
*
* Face culling relies on the primitives being drawn with a specific
* order to represent which faces are facing inside and outside the
* model. This order can be specified by calling
* cogl_pipeline_set_front_face_winding().
*
* Status: Unstable
* Since: 2.0
*/
void
cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline,
CoglPipelineCullFaceMode cull_face_mode);
/**
* cogl_pipeline_get_cull_face_mode:
*
* Return value: the cull face mode that was previously set with
* cogl_pipeline_set_cull_face_mode().
*
* Status: Unstable
* Since: 2.0
*/
CoglPipelineCullFaceMode
cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline);
/**
* cogl_pipeline_set_front_face_winding:
*
* The order of the vertices within a primitive specifies whether it
* is considered to be front or back facing. This function specifies
* which order is considered to be the front
* faces. %COGL_WINDING_COUNTER_CLOCKWISE sets the front faces to
* primitives with vertices in a counter-clockwise order and
* %COGL_WINDING_CLOCKWISE sets them to be clockwise. The default is
* %COGL_WINDING_COUNTER_CLOCKWISE.
*
* Status: Unstable
* Since: 2.0
*/
void
cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline,
CoglWinding front_winding);
/**
* cogl_pipeline_set_front_face_winding:
*
* The order of the vertices within a primitive specifies whether it
* is considered to be front or back facing. This function specifies
* which order is considered to be the front
* faces. %COGL_WINDING_COUNTER_CLOCKWISE sets the front faces to
* primitives with vertices in a counter-clockwise order and
* %COGL_WINDING_CLOCKWISE sets them to be clockwise. The default is
* %COGL_WINDING_COUNTER_CLOCKWISE.
*
* Status: Unstable
* Since: 2.0
*/
CoglWinding
cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline);
#endif /* COGL_ENABLE_EXPERIMENTAL_API */ #endif /* COGL_ENABLE_EXPERIMENTAL_API */
G_END_DECLS G_END_DECLS

View File

@ -2460,12 +2460,8 @@ _cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline)
_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) if (ctx->legacy_backface_culling_enabled)
{ cogl_pipeline_set_cull_face_mode (pipeline,
CoglPipelineCullFaceState state; COGL_PIPELINE_CULL_FACE_MODE_BACK);
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

View File

@ -702,6 +702,21 @@ typedef enum
COGL_COLOR_MASK_ALL = (COGL_COLOR_MASK_RED | COGL_COLOR_MASK_GREEN | COGL_COLOR_MASK_BLUE | COGL_COLOR_MASK_ALPHA) COGL_COLOR_MASK_ALL = (COGL_COLOR_MASK_RED | COGL_COLOR_MASK_GREEN | COGL_COLOR_MASK_BLUE | COGL_COLOR_MASK_ALPHA)
} CoglColorMask; } CoglColorMask;
/**
* CoglWinding:
* @COGL_WINDING_CLOCKWISE: Vertices are in a clockwise order
* @COGL_WINDING_COUNTER_CLOCKWISE: Vertices are in a counter-clockwise order
*
* Enum used to represent the two directions of rotation. This can be
* used to set the front face for culling by calling
* cogl_pipeline_set_front_face_winding().
*/
typedef enum
{
COGL_WINDING_CLOCKWISE,
COGL_WINDING_COUNTER_CLOCKWISE
} CoglWinding;
G_END_DECLS G_END_DECLS
#endif /* __COGL_TYPES_H__ */ #endif /* __COGL_TYPES_H__ */

View File

@ -570,6 +570,11 @@ cogl_pipeline_get_point_size
cogl_pipeline_get_color_mask cogl_pipeline_get_color_mask
cogl_pipeline_set_color_mask cogl_pipeline_set_color_mask
CoglPipelineCullFaceMode
cogl_pipeline_set_cull_face_mode
CoglWinding
cogl_pipeline_set_front_face_winding
cogl_pipeline_set_layer_texture cogl_pipeline_set_layer_texture
cogl_pipeline_get_layer_texture cogl_pipeline_get_layer_texture
CoglMaterialFilter CoglMaterialFilter