summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2011-11-08 13:58:33 +0000
committerNeil Roberts <neil@linux.intel.com>2011-11-14 18:40:27 +0000
commit5369b3c601fc537db6712c27a5453fa11236c66b (patch)
tree7e8ed606a91d6a840381bdbe2667ca79408973f4
parent8be44f98766b31ac09901c006cba7c260a3bda5e (diff)
downloadcogl-5369b3c601fc537db6712c27a5453fa11236c66b.tar.gz
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>
-rw-r--r--cogl/cogl-framebuffer.c2
-rw-r--r--cogl/cogl-pipeline-private.h14
-rw-r--r--cogl/cogl-pipeline-state-private.h8
-rw-r--r--cogl/cogl-pipeline-state.c60
-rw-r--r--cogl/cogl-pipeline-state.h91
-rw-r--r--cogl/cogl-pipeline.c8
-rw-r--r--cogl/cogl-types.h15
-rw-r--r--doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt5
8 files changed, 165 insertions, 38 deletions
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 3144c952..e28d4489 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -1132,7 +1132,7 @@ notify_buffers_changed (CoglFramebuffer *old_draw_buffer,
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_get_cull_face_mode (ctx->current_pipeline) !=
COGL_PIPELINE_CULL_FACE_MODE_NONE)
{
ctx->current_pipeline_changes_since_flush |=
diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h
index 57f3503e..4d045364 100644
--- a/cogl/cogl-pipeline-private.h
+++ b/cogl/cogl-pipeline-private.h
@@ -298,20 +298,6 @@ 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 */
diff --git a/cogl/cogl-pipeline-state-private.h b/cogl/cogl-pipeline-state-private.h
index dd00f005..d93771bc 100644
--- a/cogl/cogl-pipeline-state-private.h
+++ b/cogl/cogl-pipeline-state-private.h
@@ -35,14 +35,6 @@ 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);
diff --git a/cogl/cogl-pipeline-state.c b/cogl/cogl-pipeline-state.c
index 78102d86..db662f4f 100644
--- a/cogl/cogl-pipeline-state.c
+++ b/cogl/cogl-pipeline-state.c
@@ -1177,22 +1177,20 @@ _cogl_pipeline_set_fog_state (CoglPipeline *pipeline,
}
void
-_cogl_pipeline_set_cull_face_state (CoglPipeline *pipeline,
- const CoglPipelineCullFaceState *
- cull_face_state)
+cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline,
+ CoglPipelineCullFaceMode cull_face_mode)
{
CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
CoglPipeline *authority;
- CoglPipelineCullFaceState *current_cull_face_state;
+ CoglPipelineCullFaceState *cull_face_state;
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
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 &&
- current_cull_face_state->front_winding == cull_face_state->front_winding)
+ if (cull_face_state->mode == cull_face_mode)
return;
/* - 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);
- 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_cull_face_state_equal);
}
CoglPipelineCullFaceMode
-_cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline)
+cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline)
{
CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE;
CoglPipeline *authority;
@@ -1222,6 +1250,20 @@ _cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline)
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
cogl_pipeline_get_point_size (CoglPipeline *pipeline)
{
diff --git a/cogl/cogl-pipeline-state.h b/cogl/cogl-pipeline-state.h
index 7015b00c..5dfd21a1 100644
--- a/cogl/cogl-pipeline-state.h
+++ b/cogl/cogl-pipeline-state.h
@@ -686,6 +686,97 @@ void
cogl_pipeline_get_depth_state (CoglPipeline *pipeline,
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 */
G_END_DECLS
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index 60e96eb2..907f692c 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -2460,12 +2460,8 @@ _cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline)
_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);
- }
+ cogl_pipeline_set_cull_face_mode (pipeline,
+ COGL_PIPELINE_CULL_FACE_MODE_BACK);
}
void
diff --git a/cogl/cogl-types.h b/cogl/cogl-types.h
index c93bde84..b8edb695 100644
--- a/cogl/cogl-types.h
+++ b/cogl/cogl-types.h
@@ -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)
} 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
#endif /* __COGL_TYPES_H__ */
diff --git a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
index f8a1185a..0073408e 100644
--- a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
+++ b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt
@@ -570,6 +570,11 @@ cogl_pipeline_get_point_size
cogl_pipeline_get_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_get_layer_texture
CoglMaterialFilter