summaryrefslogtreecommitdiff
path: root/cogl
diff options
context:
space:
mode:
authorRobert Bragg <robert@linux.intel.com>2010-05-26 11:33:32 +0100
committerRobert Bragg <robert@linux.intel.com>2010-06-15 15:26:28 +0100
commitdab4ddc7184b25274c24fcec4c1e2d9dfff5e94a (patch)
tree7b9691360d1eb7c5807a473152530d84c183ce71 /cogl
parentfca054e949476d3434df28f3f0ded9a9ca37f345 (diff)
downloadcogl-dab4ddc7184b25274c24fcec4c1e2d9dfff5e94a.tar.gz
material: Make CoglMaterial responsible for depth state
This redirects the legacy depth testing APIs through CoglMaterial and adds a new experimental cogl_material_ API for handling the depth testing state. This adds the following new functions: cogl_material_set_depth_test_enabled cogl_material_get_depth_test_enabled cogl_material_set_depth_writing_enabled cogl_material_get_depth_writing_enabled cogl_material_set_depth_test_function cogl_material_get_depth_test_function cogl_material_set_depth_range cogl_material_get_depth_range As with other experimental Cogl API you need to define COGL_ENABLE_EXPERIMENTAL_API to access them and their stability isn't yet guaranteed.
Diffstat (limited to 'cogl')
-rw-r--r--cogl/cogl-context.c8
-rw-r--r--cogl/cogl-context.h8
-rw-r--r--cogl/cogl-material-private.h19
-rw-r--r--cogl/cogl-material.c323
-rw-r--r--cogl/cogl-material.h207
-rw-r--r--cogl/cogl-types.h25
-rw-r--r--cogl/cogl.c28
-rw-r--r--cogl/cogl.h6
8 files changed, 596 insertions, 28 deletions
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index e227594f..585e124f 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -127,6 +127,14 @@ cogl_create_context (void)
_context->gl_blend_enable_cache = FALSE;
+ _context->depth_test_enabled_cache = FALSE;
+ _context->depth_test_function_cache = COGL_DEPTH_TEST_FUNCTION_LESS;
+ _context->depth_writing_enabled_cache = TRUE;
+ _context->depth_range_near_cache = 0;
+ _context->depth_range_far_cache = 1;
+
+ _context->legacy_depth_test_enabled = FALSE;
+
_context->framebuffer_stack = _cogl_create_framebuffer_stack ();
window_buffer = _cogl_onscreen_new ();
diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h
index 530184f0..a56f465d 100644
--- a/cogl/cogl-context.h
+++ b/cogl/cogl-context.h
@@ -109,6 +109,14 @@ typedef struct
gboolean gl_blend_enable_cache;
+ gboolean depth_test_enabled_cache;
+ CoglDepthTestFunction depth_test_function_cache;
+ gboolean depth_writing_enabled_cache;
+ float depth_range_near_cache;
+ float depth_range_far_cache;
+
+ gboolean legacy_depth_test_enabled;
+
/* PBOs */
/* This can be used to check if a pbo is bound */
CoglBuffer *current_pbo;
diff --git a/cogl/cogl-material-private.h b/cogl/cogl-material-private.h
index 770b6005..f98bdb38 100644
--- a/cogl/cogl-material-private.h
+++ b/cogl/cogl-material-private.h
@@ -311,8 +311,9 @@ typedef enum _CoglMaterialState
COGL_MATERIAL_STATE_ALPHA_FUNC = 1L<<4,
COGL_MATERIAL_STATE_BLEND = 1L<<5,
COGL_MATERIAL_STATE_USER_SHADER = 1L<<6,
+ COGL_MATERIAL_STATE_DEPTH = 1L<<7,
- COGL_MATERIAL_STATE_REAL_BLEND_ENABLE = 1L<<7,
+ COGL_MATERIAL_STATE_REAL_BLEND_ENABLE = 1L<<8,
COGL_MATERIAL_STATE_ALL_SPARSE =
COGL_MATERIAL_STATE_COLOR |
@@ -321,7 +322,8 @@ typedef enum _CoglMaterialState
COGL_MATERIAL_STATE_LIGHTING |
COGL_MATERIAL_STATE_ALPHA_FUNC |
COGL_MATERIAL_STATE_BLEND |
- COGL_MATERIAL_STATE_USER_SHADER,
+ COGL_MATERIAL_STATE_USER_SHADER |
+ COGL_MATERIAL_STATE_DEPTH,
COGL_MATERIAL_STATE_AFFECTS_BLENDING =
COGL_MATERIAL_STATE_COLOR |
@@ -335,7 +337,8 @@ typedef enum _CoglMaterialState
COGL_MATERIAL_STATE_LIGHTING |
COGL_MATERIAL_STATE_ALPHA_FUNC |
COGL_MATERIAL_STATE_BLEND |
- COGL_MATERIAL_STATE_USER_SHADER
+ COGL_MATERIAL_STATE_USER_SHADER |
+ COGL_MATERIAL_STATE_DEPTH
} CoglMaterialState;
@@ -390,10 +393,20 @@ typedef struct
typedef struct
{
+ gboolean depth_test_enabled;
+ CoglDepthTestFunction depth_test_function;
+ gboolean depth_writing_enabled;
+ float depth_range_near;
+ float depth_range_far;
+} CoglMaterialDepthState;
+
+typedef struct
+{
CoglMaterialLightingState lighting_state;
CoglMaterialAlphaFuncState alpha_state;
CoglMaterialBlendState blend_state;
CoglHandle user_program;
+ CoglMaterialDepthState depth_state;
} CoglMaterialBigState;
typedef enum
diff --git a/cogl/cogl-material.c b/cogl/cogl-material.c
index bfd0b434..f30c533c 100644
--- a/cogl/cogl-material.c
+++ b/cogl/cogl-material.c
@@ -347,6 +347,7 @@ _cogl_material_init_default_material (void)
CoglMaterialLightingState *lighting_state = &big_state->lighting_state;
CoglMaterialAlphaFuncState *alpha_state = &big_state->alpha_state;
CoglMaterialBlendState *blend_state = &big_state->blend_state;
+ CoglMaterialDepthState *depth_state = &big_state->depth_state;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@@ -409,6 +410,13 @@ _cogl_material_init_default_material (void)
big_state->user_program = COGL_INVALID_HANDLE;
+ /* The same as the GL defaults */
+ depth_state->depth_test_enabled = FALSE;
+ depth_state->depth_test_function = COGL_DEPTH_TEST_FUNCTION_LESS;
+ depth_state->depth_writing_enabled = TRUE;
+ depth_state->depth_range_near = 0;
+ depth_state->depth_range_far = 1;
+
ctx->default_material = _cogl_material_handle_new (material);
}
@@ -989,6 +997,13 @@ _cogl_material_copy_differences (CoglMaterial *dest,
big_state->user_program = COGL_INVALID_HANDLE;
}
+ if (differences & COGL_MATERIAL_STATE_DEPTH)
+ {
+ memcpy (&big_state->depth_state,
+ &src->big_state->depth_state,
+ sizeof (CoglMaterialDepthState));
+ }
+
/* XXX: we shouldn't bother doing this in most cases since
* _copy_differences is typically used to initialize material state
* by copying it from the current authority, so it's not actually
@@ -2891,6 +2906,15 @@ _cogl_material_blend_state_equal (CoglMaterial *authority0,
}
static gboolean
+_cogl_material_depth_state_equal (CoglMaterial *authority0,
+ CoglMaterial *authority1)
+{
+ return memcmp (&authority0->big_state->depth_state,
+ &authority1->big_state->depth_state,
+ sizeof (CoglMaterialDepthState)) == 0;
+}
+
+static gboolean
_cogl_material_layers_equal (CoglMaterial *authority0,
CoglMaterial *authority1)
{
@@ -3103,6 +3127,19 @@ _cogl_material_equal (CoglHandle handle0,
return FALSE;
}
+ if (materials_difference & COGL_MATERIAL_STATE_DEPTH)
+ {
+ CoglMaterial *authority0 =
+ _cogl_material_get_authority (material0,
+ COGL_MATERIAL_STATE_DEPTH);
+ CoglMaterial *authority1 =
+ _cogl_material_get_authority (material1,
+ COGL_MATERIAL_STATE_DEPTH);
+
+ if (!_cogl_material_depth_state_equal (authority0, authority1))
+ return FALSE;
+ }
+
if (materials_difference & COGL_MATERIAL_STATE_LAYERS)
{
CoglMaterial *authority0 =
@@ -3888,6 +3925,200 @@ _cogl_material_set_user_program (CoglHandle handle,
handle_automatic_blend_enable (material, state);
}
+void
+cogl_material_set_depth_test_enabled (CoglHandle handle,
+ gboolean enable)
+{
+ CoglMaterial *material = COGL_MATERIAL (handle);
+ CoglMaterialState state = COGL_MATERIAL_STATE_DEPTH;
+ CoglMaterial *authority;
+ CoglMaterialDepthState *depth_state;
+
+ g_return_if_fail (cogl_is_material (handle));
+
+ authority = _cogl_material_get_authority (material, state);
+
+ depth_state = &authority->big_state->depth_state;
+ if (depth_state->depth_test_enabled == enable)
+ return;
+
+ /* - Flush journal primitives referencing the current state.
+ * - Make sure the material has no dependants so it may be modified.
+ * - If the material isn't currently an authority for the state being
+ * changed, then initialize that state from the current authority.
+ */
+ _cogl_material_pre_change_notify (material, state, NULL);
+
+ material->big_state->depth_state.depth_test_enabled = enable;
+
+ _cogl_material_update_authority (material, authority, state,
+ _cogl_material_depth_state_equal);
+}
+
+gboolean
+cogl_material_get_depth_test_enabled (CoglHandle handle)
+{
+ CoglMaterial *material = COGL_MATERIAL (handle);
+ CoglMaterial *authority;
+
+ g_return_val_if_fail (cogl_is_material (handle), FALSE);
+
+ authority =
+ _cogl_material_get_authority (material, COGL_MATERIAL_STATE_DEPTH);
+
+ return authority->big_state->depth_state.depth_test_enabled;
+}
+
+void
+cogl_material_set_depth_writing_enabled (CoglHandle handle,
+ gboolean enable)
+{
+ CoglMaterial *material = COGL_MATERIAL (handle);
+ CoglMaterialState state = COGL_MATERIAL_STATE_DEPTH;
+ CoglMaterial *authority;
+ CoglMaterialDepthState *depth_state;
+
+ g_return_if_fail (cogl_is_material (handle));
+
+ authority = _cogl_material_get_authority (material, state);
+
+ depth_state = &authority->big_state->depth_state;
+ if (depth_state->depth_writing_enabled == enable)
+ return;
+
+ /* - Flush journal primitives referencing the current state.
+ * - Make sure the material has no dependants so it may be modified.
+ * - If the material isn't currently an authority for the state being
+ * changed, then initialize that state from the current authority.
+ */
+ _cogl_material_pre_change_notify (material, state, NULL);
+
+ material->big_state->depth_state.depth_writing_enabled = enable;
+
+ _cogl_material_update_authority (material, authority, state,
+ _cogl_material_depth_state_equal);
+}
+
+gboolean
+cogl_material_get_depth_writing_enabled (CoglHandle handle)
+{
+ CoglMaterial *material = COGL_MATERIAL (handle);
+ CoglMaterial *authority;
+
+ g_return_val_if_fail (cogl_is_material (handle), TRUE);
+
+ authority =
+ _cogl_material_get_authority (material, COGL_MATERIAL_STATE_DEPTH);
+
+ return authority->big_state->depth_state.depth_writing_enabled;
+}
+
+void
+cogl_material_set_depth_test_function (CoglHandle handle,
+ CoglDepthTestFunction function)
+{
+ CoglMaterial *material = COGL_MATERIAL (handle);
+ CoglMaterialState state = COGL_MATERIAL_STATE_DEPTH;
+ CoglMaterial *authority;
+ CoglMaterialDepthState *depth_state;
+
+ g_return_if_fail (cogl_is_material (handle));
+
+ authority = _cogl_material_get_authority (material, state);
+
+ depth_state = &authority->big_state->depth_state;
+ if (depth_state->depth_test_function == function)
+ return;
+
+ /* - Flush journal primitives referencing the current state.
+ * - Make sure the material has no dependants so it may be modified.
+ * - If the material isn't currently an authority for the state being
+ * changed, then initialize that state from the current authority.
+ */
+ _cogl_material_pre_change_notify (material, state, NULL);
+
+ material->big_state->depth_state.depth_test_function = function;
+
+ _cogl_material_update_authority (material, authority, state,
+ _cogl_material_depth_state_equal);
+}
+
+CoglDepthTestFunction
+cogl_material_get_depth_test_function (CoglHandle handle)
+{
+ CoglMaterial *material = COGL_MATERIAL (handle);
+ CoglMaterial *authority;
+
+ g_return_val_if_fail (cogl_is_material (handle),
+ COGL_DEPTH_TEST_FUNCTION_LESS);
+
+ authority =
+ _cogl_material_get_authority (material, COGL_MATERIAL_STATE_DEPTH);
+
+ return authority->big_state->depth_state.depth_test_function;
+}
+
+
+gboolean
+cogl_material_set_depth_range (CoglHandle handle,
+ float near,
+ float far,
+ GError **error)
+{
+#ifndef COGL_HAS_GLES
+ CoglMaterial *material = COGL_MATERIAL (handle);
+ CoglMaterialState state = COGL_MATERIAL_STATE_DEPTH;
+ CoglMaterial *authority;
+ CoglMaterialDepthState *depth_state;
+
+ g_return_val_if_fail (cogl_is_material (handle), FALSE);
+
+ authority = _cogl_material_get_authority (material, state);
+
+ depth_state = &authority->big_state->depth_state;
+ if (depth_state->depth_range_near == near &&
+ depth_state->depth_range_far == far)
+ return TRUE;
+
+ /* - Flush journal primitives referencing the current state.
+ * - Make sure the material has no dependants so it may be modified.
+ * - If the material isn't currently an authority for the state being
+ * changed, then initialize that state from the current authority.
+ */
+ _cogl_material_pre_change_notify (material, state, NULL);
+
+ material->big_state->depth_state.depth_range_near = near;
+ material->big_state->depth_state.depth_range_far = far;
+
+ _cogl_material_update_authority (material, authority, state,
+ _cogl_material_depth_state_equal);
+ return TRUE;
+#else
+ g_set_error (error,
+ COGL_ERROR,
+ COGL_ERROR_MISSING_FEATURE,
+ "glDepthRange not available on GLES 1");
+ return FALSE;
+#endif
+}
+
+void
+cogl_material_get_depth_range (CoglHandle handle,
+ float *near,
+ float *far)
+{
+ CoglMaterial *material = COGL_MATERIAL (handle);
+ CoglMaterial *authority;
+
+ g_return_if_fail (cogl_is_material (handle));
+
+ authority =
+ _cogl_material_get_authority (material, COGL_MATERIAL_STATE_DEPTH);
+
+ *near = authority->big_state->depth_state.depth_range_near;
+ *far = authority->big_state->depth_state.depth_range_far;
+}
+
static CoglMaterialLayer *
_cogl_material_layer_copy (CoglMaterialLayer *src)
{
@@ -5838,9 +6069,45 @@ blend_factor_uses_constant (GLenum blend_factor)
#endif
static void
-_cogl_material_flush_color_blend_alpha_state (CoglMaterial *material,
- unsigned long materials_difference,
- gboolean skip_gl_color)
+flush_depth_state (CoglMaterialDepthState *depth_state)
+{
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+ if (ctx->depth_test_function_cache != depth_state->depth_test_function)
+ {
+ GE (glDepthFunc (depth_state->depth_test_function));
+ ctx->depth_test_function_cache = depth_state->depth_test_function;
+ }
+
+ if (ctx->depth_writing_enabled_cache != depth_state->depth_writing_enabled)
+ {
+ GE (glDepthMask (depth_state->depth_writing_enabled ?
+ GL_TRUE : GL_FALSE));
+ ctx->depth_writing_enabled_cache = depth_state->depth_writing_enabled;
+ }
+
+#ifndef COGL_HAS_GLES
+ if (ctx->depth_range_near_cache != depth_state->depth_range_near ||
+ ctx->depth_range_far_cache != depth_state->depth_range_far)
+ {
+#ifdef COGL_HAS_GLES2
+ GE (glDepthRangef (depth_state->depth_range_near,
+ depth_state->depth_range_far));
+#else
+ GE (glDepthRange (depth_state->depth_range_near,
+ depth_state->depth_range_far));
+#endif
+ ctx->depth_range_near_cache = depth_state->depth_range_near;
+ ctx->depth_range_far_cache = depth_state->depth_range_far;
+ }
+#endif /* COGL_HAS_GLES */
+}
+
+static void
+_cogl_material_flush_color_blend_alpha_depth_state (
+ CoglMaterial *material,
+ unsigned long materials_difference,
+ gboolean skip_gl_color)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@@ -5948,12 +6215,36 @@ _cogl_material_flush_color_blend_alpha_state (CoglMaterial *material,
alpha_state->alpha_func_reference));
}
+ if (materials_difference & COGL_MATERIAL_STATE_DEPTH)
+ {
+ CoglMaterial *authority =
+ _cogl_material_get_authority (material, COGL_MATERIAL_STATE_DEPTH);
+ CoglMaterialDepthState *depth_state = &authority->big_state->depth_state;
+
+ if (depth_state->depth_test_enabled)
+ {
+ if (ctx->depth_test_enabled_cache != TRUE)
+ {
+ GE (glEnable (GL_DEPTH_TEST));
+ ctx->depth_test_enabled_cache = depth_state->depth_test_enabled;
+ }
+ flush_depth_state (depth_state);
+ }
+ else if (ctx->depth_test_enabled_cache != FALSE)
+ {
+ GE (glDisable (GL_DEPTH_TEST));
+ ctx->depth_test_enabled_cache = depth_state->depth_test_enabled;
+ }
+ }
+
if (material->real_blend_enable != ctx->gl_blend_enable_cache)
{
if (material->real_blend_enable)
GE (glEnable (GL_BLEND));
else
GE (glDisable (GL_BLEND));
+ /* XXX: we shouldn't update any other blend state if blending
+ * is disabled! */
ctx->gl_blend_enable_cache = material->real_blend_enable;
}
}
@@ -6129,9 +6420,9 @@ _cogl_material_flush_common_gl_state (CoglMaterial *material,
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
- _cogl_material_flush_color_blend_alpha_state (material,
- materials_difference,
- skip_gl_color);
+ _cogl_material_flush_color_blend_alpha_depth_state (material,
+ materials_difference,
+ skip_gl_color);
state.i = 0;
state.layer_differences = layer_differences;
@@ -6568,16 +6859,18 @@ _cogl_material_apply_legacy_state (CoglHandle handle)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
+ /* It was a mistake that we ever copied the OpenGL style API for
+ * associating these things directly with the context when we
+ * originally wrote Cogl. Until the corresponding deprecated APIs
+ * can be removed though we now shoehorn the state changes through
+ * the cogl_material API instead.
+ */
+
if (ctx->current_program)
- {
- /* It was a mistake that we ever copied the OpenGL style API for
- * making a program current (cogl_program_use) on the context.
- * Until cogl_program_use is removed we will transparently set
- * the program on the material because the cogl-material code is
- * in the best position to juggle the corresponding GL state. */
- _cogl_material_set_user_program (handle,
- ctx->current_program);
- }
+ _cogl_material_set_user_program (handle, ctx->current_program);
+
+ if (ctx->legacy_depth_test_enabled)
+ cogl_material_set_depth_test_enabled (handle, TRUE);
}
void
diff --git a/cogl/cogl-material.h b/cogl/cogl-material.h
index 12c9b39a..0071dc36 100644
--- a/cogl/cogl-material.h
+++ b/cogl/cogl-material.h
@@ -944,6 +944,213 @@ cogl_material_layer_get_wrap_mode_s (CoglHandle layer);
CoglMaterialWrapMode
cogl_material_layer_get_wrap_mode_t (CoglHandle layer);
+
+/* XXX: should this be CoglMaterialDepthTestFunction?
+ * It makes it very verbose but would be consistent with
+ * CoglMaterialWrapMode */
+
+/**
+ * CoglDepthTestFunction:
+ * @COGL_DEPTH_TEST_FUNCTION_NEVER: Never passes.
+ * @COGL_DEPTH_TEST_FUNCTION_LESS: Passes if the fragment's depth
+ * value is less than the value currently in the depth buffer.
+ * @COGL_DEPTH_TEST_FUNCTION_EQUAL: Passes if the fragment's depth
+ * value is equal to the value currently in the depth buffer.
+ * @COGL_DEPTH_TEST_FUNCTION_LEQUAL: Passes if the fragment's depth
+ * value is less or equal to the value currently in the depth buffer.
+ * @COGL_DEPTH_TEST_FUNCTION_GREATER: Passes if the fragment's depth
+ * value is greater than the value currently in the depth buffer.
+ * @COGL_DEPTH_TEST_FUNCTION_NOTEQUAL: Passes if the fragment's depth
+ * value is not equal to the value currently in the depth buffer.
+ * @COGL_DEPTH_TEST_FUNCTION_GEQUAL: Passes if the fragment's depth
+ * value greater than or equal to the value currently in the depth buffer.
+ * @COGL_DEPTH_TEST_FUNCTION_ALWAYS: Always passes.
+ *
+ * When using depth testing one of these functions is used to compare
+ * the depth of an incoming fragment against the depth value currently
+ * stored in the depth buffer. The function is changed using
+ * cogl_material_set_depth_test_function().
+ *
+ * The test is only done when depth testing is explicitly enabled. (See
+ * cogl_material_set_depth_test_enabled())
+ */
+typedef enum
+{
+ COGL_DEPTH_TEST_FUNCTION_NEVER = GL_NEVER,
+ COGL_DEPTH_TEST_FUNCTION_LESS = GL_LESS,
+ COGL_DEPTH_TEST_FUNCTION_EQUAL = GL_EQUAL,
+ COGL_DEPTH_TEST_FUNCTION_LEQUAL = GL_LEQUAL,
+ COGL_DEPTH_TEST_FUNCTION_GREATER = GL_GREATER,
+ COGL_DEPTH_TEST_FUNCTION_NOTEQUAL = GL_NOTEQUAL,
+ COGL_DEPTH_TEST_FUNCTION_GEQUAL = GL_GEQUAL,
+ COGL_DEPTH_TEST_FUNCTION_ALWAYS = GL_ALWAYS
+} CoglDepthTestFunction;
+/* XXX: to avoid having to split this into a separate include that can
+ * in #included internally without needing the
+ * COGL_ENABLE_EXPERIMENTAL_API define this isn't guarded. It's still
+ * considered experimental but it's guarded instead by the fact that
+ * there's no corresponding API. */
+
+#ifdef COGL_ENABLE_EXPERIMENTAL_API
+
+/**
+ * cogl_material_set_depth_test_enabled:
+ * @handle: A CoglMaterial handle
+ * @enable: The enable state you want
+ *
+ * Enables or disables depth testing according to the value of
+ * @enable.
+ *
+ * If depth testing is enable then the #CoglDepthTestFunction set
+ * using cogl_material_set_depth_test_function() us used to evaluate
+ * the depth value of incoming fragments against the corresponding
+ * value stored in the current depth buffer, and if the test passes
+ * then the fragments depth value is used to update the depth buffer.
+ * (unless you have disabled depth writing via
+ * cogl_material_set_depth_writing_enabled ())
+ *
+ * By default depth testing is disabled.
+ *
+ * Since: 1.4
+ */
+void
+cogl_material_set_depth_test_enabled (CoglHandle handle,
+ gboolean enable);
+
+/**
+ * cogl_material_get_depth_test_enabled:
+ * @handle: A CoglMaterial handle
+ *
+ * Gets the current depth test enabled state as previously set by
+ * cogl_material_set_depth_test_enabled().
+ *
+ * Returns: The material's current depth test enabled state.
+ * Since: 1.4
+ */
+gboolean
+cogl_material_get_depth_test_enabled (CoglHandle handle);
+
+/**
+ * cogl_material_set_depth_writing_enabled:
+ * @handle: A CoglMaterial handle
+ * @enable: The enable state you want
+ *
+ * Enables or disables depth buffer writing according to the value of
+ * @enable. Normally when depth testing is enabled and the comparison
+ * between a fragment's depth value and the corresponding depth buffer
+ * value passes then the fragment's depth is written to the depth
+ * buffer unless writing is disabled here.
+ *
+ * By default depth writing is enabled
+ *
+ * Since: 1.4
+ */
+void
+cogl_material_set_depth_writing_enabled (CoglHandle handle,
+ gboolean enable);
+
+/**
+ * cogl_material_get_depth_writing_enabled:
+ * @handle: A CoglMaterial handle
+ * Since: 1.4
+ *
+ * Gets the depth writing enable state as set by the corresponding
+ * cogl_material_set_depth_writing_enabled.
+ *
+ * Returns: The current depth writing enable state
+ * Since: 1.4
+ */
+gboolean
+cogl_material_get_depth_writing_enabled (CoglHandle handle);
+
+/**
+ * cogl_material_set_depth_test_function:
+ * @handle: A CoglMaterial handle
+ * @function: The #CoglDepthTestFunction to set
+ *
+ * Sets the #CoglDepthTestFunction used to compare the depth value of
+ * an incoming fragment against the corresponding value in the current
+ * depth buffer.
+ *
+ * Since: 1.4
+ */
+void
+cogl_material_set_depth_test_function (CoglHandle handle,
+ CoglDepthTestFunction function);
+
+/**
+ * cogl_material_get_depth_test_function:
+ * @handle: A CoglMaterial handle
+ *
+ * Gets the current depth test enable state as previously set via
+ * cogl_material_set_depth_test_enabled().
+ *
+ * Returns: The current depth test enable state.
+ * Since: 1.4
+ */
+CoglDepthTestFunction
+cogl_material_get_depth_test_function (CoglHandle handle);
+
+/**
+ * cogl_material_set_depth_range:
+ * @handle: A CoglMaterial handle
+ * @near: The near component of the desired depth range which will be
+ * clamped to the range [0, 1]
+ * @far: The far component of the desired depth range which will be
+ * clamped to the range [0, 1]
+ * @error: location to store an error of type #CoglError
+ *
+ * Sets the range to map depth values in normalized device coordinates
+ * to before writing out to a depth buffer.
+ *
+ * After your geometry has be transformed, clipped and had perspective
+ * division applied placing it in normalized device
+ * coordinates all depth values between the near and far z clipping
+ * planes are in the range -1 to 1. Before writing any depth value to
+ * the depth buffer though the value is mapped into the range [0, 1].
+ *
+ * With this function you can change the range which depth values are
+ * mapped too although the range must still lye within the range [0,
+ * 1].
+ *
+ * If your driver does not support this feature (for example you are
+ * using GLES 1 drivers) then this will return %FALSE and set an error
+ * if @error isn't NULL. You can check ahead of time for the
+ * %COGL_FEATURE_DEPTH_RANGE feature with cogl_features_available() to
+ * know if this function will succeed.
+ *
+ * By default normalized device coordinate depth values are mapped to
+ * the full range of depth buffer values, [0, 1].
+ *
+ * Returns: %TRUE if driver support is available else %FALSE.
+ *
+ * Since: 1.4
+ */
+gboolean
+cogl_material_set_depth_range (CoglHandle handle,
+ float near,
+ float far,
+ GError **error);
+
+/**
+ * cogl_material_get_depth_range_mapping:
+ * @handle: A CoglMaterial handle
+ * @near: A pointer to store the near component of the depth range
+ * @far: A pointer to store the far component of the depth range
+ *
+ * Gets the current range to which normalized depth values are mapped
+ * before writing to the depth buffer. This corresponds to the range
+ * set with cogl_material_set_depth_range().
+ *
+ * Since: 1.4
+ */
+void
+cogl_material_get_depth_range (CoglHandle handle,
+ float *near,
+ float *far);
+
+#endif /* COGL_ENABLE_EXPERIMENTAL_API */
+
G_END_DECLS
#endif /* __COGL_MATERIAL_H__ */
diff --git a/cogl/cogl-types.h b/cogl/cogl-types.h
index 68b6dca4..54d6d5e2 100644
--- a/cogl/cogl-types.h
+++ b/cogl/cogl-types.h
@@ -233,6 +233,7 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
* @COGL_FEATURE_UNSIGNED_INT_INDICES: Set if
* %COGL_INDICES_TYPE_UNSIGNED_INT is supported in
* cogl_vertex_buffer_indices_new().
+ * @COGL_FEATURE_DEPTH_RANGE: cogl_material_set_depth_range() support
*
* Flags for the supported features.
*
@@ -252,7 +253,8 @@ typedef enum
COGL_FEATURE_STENCIL_BUFFER = (1 << 10),
COGL_FEATURE_VBOS = (1 << 11),
COGL_FEATURE_PBOS = (1 << 12),
- COGL_FEATURE_UNSIGNED_INT_INDICES = (1 << 13)
+ COGL_FEATURE_UNSIGNED_INT_INDICES = (1 << 13),
+ COGL_FEATURE_DEPTH_RANGE = (1 << 14)
} CoglFeatureFlags;
/**
@@ -403,6 +405,27 @@ typedef enum { /*< prefix=COGL_BLEND_STRING_ERROR >*/
GQuark
cogl_blend_string_error_quark (void);
+#define COGL_ERROR (_cogl_error_quark ())
+
+/**
+ * CoglError:
+ * @COGL_ERROR_MISSING_FEATURE: You tried to use a feature not
+ * currently available; likely because of missing driver support.
+ *
+ * Error enumeration for Cogl
+ *
+ * Currently this is only used by Cogl API marked as experimental so
+ * this enum should also be considered experimental.
+ *
+ * Since: 1.4
+ */
+typedef enum { /*< prefix=COGL_ERROR >*/
+ COGL_ERROR_MISSING_FEATURE
+} CoglError;
+
+GQuark
+_cogl_error_quark (void);
+
G_END_DECLS
#endif /* __COGL_TYPES_H__ */
diff --git a/cogl/cogl.c b/cogl/cogl.c
index 81467b74..46e17ac7 100644
--- a/cogl/cogl.c
+++ b/cogl/cogl.c
@@ -287,25 +287,28 @@ _cogl_get_enable (void)
return ctx->enable_flags;
}
+/* XXX: This API has been deprecated */
void
cogl_set_depth_test_enabled (gboolean setting)
{
- /* Currently the journal can't track changes to depth state... */
- _cogl_journal_flush ();
+ _COGL_GET_CONTEXT (ctx, NO_RETVAL);
- if (setting)
- {
- glEnable (GL_DEPTH_TEST);
- glDepthFunc (GL_LEQUAL);
- }
+ if (ctx->legacy_depth_test_enabled == setting)
+ return;
+
+ ctx->legacy_depth_test_enabled = setting;
+ if (ctx->legacy_depth_test_enabled)
+ ctx->legacy_state_set++;
else
- glDisable (GL_DEPTH_TEST);
+ ctx->legacy_state_set--;
}
+/* XXX: This API has been deprecated */
gboolean
cogl_get_depth_test_enabled (void)
{
- return glIsEnabled (GL_DEPTH_TEST) == GL_TRUE ? TRUE : FALSE;
+ _COGL_GET_CONTEXT (ctx, FALSE);
+ return ctx->legacy_depth_test_enabled;
}
void
@@ -1136,3 +1139,10 @@ _cogl_transform_point (const CoglMatrix *matrix_mv,
#undef VIEWPORT_TRANSFORM_X
#undef VIEWPORT_TRANSFORM_Y
+
+GQuark
+_cogl_error_quark (void)
+{
+ return g_quark_from_static_string ("cogl-error-quark");
+}
+
diff --git a/cogl/cogl.h b/cogl/cogl.h
index e639658d..791e1ad5 100644
--- a/cogl/cogl.h
+++ b/cogl/cogl.h
@@ -483,6 +483,9 @@ cogl_get_viewport (float v[4]);
* order specified using clutter_actor_raise() and
* clutter_actor_lower(), otherwise it will also take into account the
* actor's depth. Depth testing is disabled by default.
+ *
+ * Deprecated: 1.4: Use cogl_material_set_depth_test_enabled()
+ * instead.
*/
void
cogl_set_depth_test_enabled (gboolean setting);
@@ -493,6 +496,9 @@ cogl_set_depth_test_enabled (gboolean setting);
* Queries if depth testing has been enabled via cogl_set_depth_test_enable()
*
* Return value: %TRUE if depth testing is enabled, and %FALSE otherwise
+ *
+ * Deprecated: 1.4: Use cogl_material_get_depth_test_enabled()
+ * instead.
*/
gboolean
cogl_get_depth_test_enabled (void);