Add CoglDepthState API

Instead of simply extending the cogl_pipeline_ namespace to add api for
controlling the depth testing state we now break the api out. This adds
a CoglDepthState type that can be stack allocated. The members of the
structure are private but we have the following API to setup the state:

    cogl_depth_state_init
    cogl_depth_state_set_test_enabled
    cogl_depth_state_get_test_enabled
    cogl_depth_state_set_test_function
    cogl_depth_state_get_test_function
    cogl_depth_state_set_writing_enabled
    cogl_depth_state_get_writing_enabled
    cogl_depth_state_set_range
    cogl_depth_state_get_range

This removes the following experimental API which is now superseded:

    cogl_material_set_depth_test_enabled
    cogl_material_get_depth_test_enabled
    cogl_material_set_depth_test_function
    cogl_material_get_depth_test_function
    cogl_material_set_depth_writing_enabled
    cogl_material_get_depth_writing_enabled
    cogl_material_set_depth_range
    cogl_material_get_depth_range

Once a CoglDepthState structure is setup it can be set on a pipeline
using cogl_pipeline_set_depth_state().
This commit is contained in:
Robert Bragg 2011-04-14 18:12:03 +01:00
parent eb109e6cc0
commit 07c0b9f89f
16 changed files with 545 additions and 555 deletions

View File

@ -61,6 +61,7 @@ cogl_public_h = \
$(srcdir)/cogl-buffer.h \
$(srcdir)/cogl-color.h \
$(srcdir)/cogl-fixed.h \
$(srcdir)/cogl-depth-state.h \
$(srcdir)/cogl-material-compat.h \
$(srcdir)/cogl-pipeline.h \
$(srcdir)/cogl-vector.h \
@ -236,6 +237,8 @@ cogl_sources_c = \
$(srcdir)/cogl-matrix-private.h \
$(srcdir)/cogl-matrix-stack.c \
$(srcdir)/cogl-matrix-stack.h \
$(srcdir)/cogl-depth-state.c \
$(srcdir)/cogl-depth-state-private.h \
$(srcdir)/cogl-pipeline.c \
$(srcdir)/cogl-pipeline-private.h \
$(srcdir)/cogl-pipeline-opengl.c \

108
cogl/cogl-depth-state.c Normal file
View File

@ -0,0 +1,108 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <cogl/cogl.h>
#include "cogl-depth-state-private.h"
void
cogl_depth_state_init (CoglDepthState *state)
{
state->magic = COGL_DEPTH_STATE_MAGIC;
state->test_enabled = FALSE;
state->write_enabled = TRUE;
state->test_function = COGL_DEPTH_TEST_FUNCTION_LESS;
state->range_near = 0;
state->range_far = 1;
}
void
cogl_depth_state_set_test_enabled (CoglDepthState *state,
gboolean enabled)
{
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
state->test_enabled = enabled;
}
gboolean
cogl_depth_state_get_test_enabled (CoglDepthState *state)
{
g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
return state->test_enabled;
}
void
cogl_depth_state_set_write_enabled (CoglDepthState *state,
gboolean enabled)
{
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
state->write_enabled = enabled;
}
gboolean
cogl_depth_state_get_write_enabled (CoglDepthState *state)
{
g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
return state->write_enabled;
}
void
cogl_depth_state_set_test_function (CoglDepthState *state,
CoglDepthTestFunction function)
{
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
state->test_function = function;
}
CoglDepthTestFunction
cogl_depth_state_get_test_function (CoglDepthState *state)
{
g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE);
return state->test_function;
}
void
cogl_depth_state_set_range (CoglDepthState *state,
float near,
float far)
{
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
state->range_near = near;
state->range_far = far;
}
void
cogl_depth_state_get_range (CoglDepthState *state,
float *near_out,
float *far_out)
{
g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC);
*near_out = state->range_near;
*far_out = state->range_far;
}

261
cogl/cogl-depth-state.h Normal file
View File

@ -0,0 +1,261 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*
*/
#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cogl/cogl.h> can be included directly."
#endif
#ifndef __COGL_DEPTH_STATE_H__
#define __COGL_DEPTH_STATE_H__
G_BEGIN_DECLS
/**
* SECTION:cogl-depth-state
* @short_description: Functions for describing the depth testing
* state of your GPU.
*/
typedef struct
{
guint32 COGL_PRIVATE (magic);
gboolean COGL_PRIVATE (test_enabled);
CoglDepthTestFunction COGL_PRIVATE (test_function);
gboolean COGL_PRIVATE (write_enabled);
float COGL_PRIVATE (range_near);
float COGL_PRIVATE (range_far);
guint32 COGL_PRIVATE (padding0);
guint32 COGL_PRIVATE (padding1);
guint32 COGL_PRIVATE (padding2);
guint32 COGL_PRIVATE (padding3);
guint32 COGL_PRIVATE (padding4);
guint32 COGL_PRIVATE (padding5);
guint32 COGL_PRIVATE (padding6);
guint32 COGL_PRIVATE (padding7);
guint32 COGL_PRIVATE (padding8);
guint32 COGL_PRIVATE (padding9);
} CoglDepthState;
/**
* cogl_depth_state_init:
* @state: A #CoglDepthState struct
*
* Initializes the members of @state to their default values.
*
* You should never pass an un initialized #CoglDepthState structure
* to cogl_pipeline_set_depth_state().
*
* Since: 2.0
* Stability: Unstable
*/
void
cogl_depth_state_init (CoglDepthState *state);
/**
* cogl_depth_state_set_test_enabled:
* @state: A #CoglDepthState struct
* @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_pipeline_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_pipeline_set_depth_writing_enabled ())
*
* By default depth testing is disabled.
*
* NB: this won't directly affect the state of the GPU. You have
* to then set the state on a #CoglPipeline using
* cogl_pipeline_set_depth_state()
*
* Since: 2.0
* Stability: Unstable
*/
void
cogl_depth_state_set_test_enabled (CoglDepthState *state,
gboolean enable);
/**
* cogl_depth_state_get_test_enabled:
* @state: A #CoglDepthState struct
*
* Gets the current depth test enabled state as previously set by
* cogl_depth_state_set_test_enabled().
*
* Returns: The pipeline's current depth test enabled state.
* Since: 2.0
* Stability: Unstable
*/
gboolean
cogl_depth_state_get_test_enabled (CoglDepthState *state);
/**
* cogl_depth_state_set_write_enabled:
* @state: A #CoglDepthState struct
* @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
*
* NB: this won't directly affect the state of the GPU. You have
* to then set the state on a #CoglPipeline using
* cogl_pipeline_set_depth_state()
*
* Since: 2.0
* Stability: Unstable
*/
void
cogl_depth_state_set_write_enabled (CoglDepthState *state,
gboolean enable);
/**
* cogl_depth_state_get_write_enabled:
* @state: A #CoglDepthState struct
*
* Gets the depth writing enable state as set by the corresponding
* cogl_pipeline_set_depth_writing_enabled.
*
* Returns: The current depth writing enable state
* Since: 2.0
* Stability: Unstable
*/
gboolean
cogl_depth_state_get_write_enabled (CoglDepthState *state);
/**
* cogl_depth_state_set_test_function:
* @state: A #CoglDepthState struct
* @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.
*
* By default the depth test function is %COGL_DEPTH_TEST_FUNCTION_LESS
*
* NB: this won't directly affect the state of the GPU. You have
* to then set the state on a #CoglPipeline using
* cogl_pipeline_set_depth_state()
*
* Since: 2.0
* Stability: Unstable
*/
void
cogl_depth_state_set_test_function (CoglDepthState *state,
CoglDepthTestFunction function);
/**
* cogl_depth_state_get_test_function:
* @state: A #CoglDepthState struct
*
* Gets the current depth test enable state as previously set via
* cogl_pipeline_set_depth_test_enabled().
*
* Returns: The current depth test enable state.
* Since: 2.0
* Stability: Unstable
*/
CoglDepthTestFunction
cogl_depth_state_get_test_function (CoglDepthState *state);
/**
* cogl_depth_state_set_range:
* @state: A #CoglDepthState object
* @near_val: The near component of the desired depth range which will be
* clamped to the range [0, 1]
* @far_val: 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 if you don't use the default range
* values you will get an error reported when calling
* cogl_pipeline_set_depth_state (). 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].
*
* NB: this won't directly affect the state of the GPU. You have
* to then set the state on a #CoglPipeline using
* cogl_pipeline_set_depth_state().
*
* Since: 2.0
* Stability: Unstable
*/
void
cogl_depth_state_set_range (CoglDepthState *state,
float near_val,
float far_val);
/**
* cogl_depth_state_get_range:
* @pipeline: A #CoglPipeline object
* @near_val: A pointer to store the near component of the depth range
* @far_val: 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_pipeline_set_depth_range().
*
* Since: 2.0
* Stability: Unstable
*/
void
cogl_depth_state_get_range (CoglDepthState *state,
float *near_val,
float *far_val);
G_END_DECLS
#endif /* __COGL_DEPTH_STATE_H__ */

View File

@ -427,63 +427,6 @@ cogl_material_layer_get_wrap_mode_p (CoglMaterialLayer *layer)
return _cogl_pipeline_layer_get_wrap_mode_p (COGL_PIPELINE_LAYER (layer));
}
void
cogl_material_set_depth_test_enabled (CoglMaterial *material,
gboolean enable)
{
cogl_pipeline_set_depth_test_enabled (COGL_PIPELINE (material), enable);
}
gboolean
cogl_material_get_depth_test_enabled (CoglMaterial *material)
{
return cogl_pipeline_get_depth_test_enabled (COGL_PIPELINE (material));
}
void
cogl_material_set_depth_writing_enabled (CoglMaterial *material,
gboolean enable)
{
cogl_pipeline_set_depth_writing_enabled (COGL_PIPELINE (material), enable);
}
gboolean
cogl_material_get_depth_writing_enabled (CoglMaterial *material)
{
return cogl_pipeline_get_depth_writing_enabled (COGL_PIPELINE (material));
}
void
cogl_material_set_depth_test_function (CoglMaterial *material,
CoglDepthTestFunction function)
{
cogl_pipeline_set_depth_test_function (COGL_PIPELINE (material), function);
}
CoglDepthTestFunction
cogl_material_get_depth_test_function (CoglMaterial *material)
{
return cogl_pipeline_get_depth_test_function (COGL_PIPELINE (material));
}
gboolean
cogl_material_set_depth_range (CoglMaterial *material,
float near_val,
float far_val,
GError **error)
{
return cogl_pipeline_set_depth_range (COGL_PIPELINE (material),
near_val, far_val, error);
}
void
cogl_material_get_depth_range (CoglMaterial *material,
float *near_val,
float *far_val)
{
cogl_pipeline_get_depth_range (COGL_PIPELINE (material), near_val, far_val);
}
void
cogl_material_foreach_layer (CoglMaterial *material,
CoglMaterialLayerCallback callback,
@ -493,3 +436,19 @@ cogl_material_foreach_layer (CoglMaterial *material,
(CoglPipelineLayerCallback)callback, user_data);
}
gboolean
cogl_material_set_depth_state (CoglMaterial *material,
const CoglDepthState *state,
GError **error)
{
return cogl_pipeline_set_depth_state (COGL_PIPELINE (material),
state, error);
}
void
cogl_material_get_depth_state (CoglMaterial *material,
CoglDepthState *state_out)
{
cogl_pipeline_get_depth_state (COGL_PIPELINE (material), state_out);
}

View File

@ -32,6 +32,7 @@ G_BEGIN_DECLS
#include <cogl/cogl-types.h>
#include <cogl/cogl-matrix.h>
#include <cogl/cogl-depth-state.h>
/**
* SECTION:cogl-material
@ -1195,167 +1196,44 @@ cogl_material_layer_get_wrap_mode_p (CoglMaterialLayer *layer);
#ifdef COGL_ENABLE_EXPERIMENTAL_API
/**
* cogl_material_set_depth_test_enabled:
* cogl_material_set_depth_state:
* @material: A #CoglMaterial object
* @enable: The enable state you want
* @state: A #CoglDepthState struct
* @error: A #GError to report failures to setup the given @state.
*
* Enables or disables depth testing according to the value of
* @enable.
* This commits all the depth state configured in @state struct to the
* given @material. The configuration values are copied into the
* material so there is no requirement to keep the #CoglDepthState
* struct around if you don't need it any more.
*
* 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 ())
* Note: Since some platforms do not support the depth range feature
* it is possible for this function to fail and report an @error.
*
* By default depth testing is disabled.
* Returns: TRUE if the GPU supports all the given @state else %FALSE
* and returns an @error.
*
* Since: 1.4
* Stability: Unstable
*/
void
cogl_material_set_depth_test_enabled (CoglMaterial *material,
gboolean enable);
/**
* cogl_material_get_depth_test_enabled:
* @material: A #CoglMaterial object
*
* 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
* Since: 1.8
* Stability: Unstable
*/
gboolean
cogl_material_get_depth_test_enabled (CoglMaterial *material);
/**
* cogl_material_set_depth_writing_enabled:
* @material: A #CoglMaterial object
* @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
* Stability: Unstable
*/
void
cogl_material_set_depth_writing_enabled (CoglMaterial *material,
gboolean enable);
/**
* cogl_material_get_depth_writing_enabled:
* @material: A #CoglMaterial object
*
* 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
* Stability: Unstable
*/
gboolean
cogl_material_get_depth_writing_enabled (CoglMaterial *material);
/**
* cogl_material_set_depth_test_function:
* @material: A #CoglMaterial object
* @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
* Stability: Unstable
*/
void
cogl_material_set_depth_test_function (CoglMaterial *material,
CoglDepthTestFunction function);
/**
* cogl_material_get_depth_test_function:
* @material: A #CoglMaterial object
*
* 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
* Stability: Unstable
*/
CoglDepthTestFunction
cogl_material_get_depth_test_function (CoglMaterial *material);
/**
* cogl_material_set_depth_range:
* @material: A #CoglMaterial object
* @near_val: The near component of the desired depth range which will be
* clamped to the range [0, 1]
* @far_val: 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
* Stability: Unstable
*/
gboolean
cogl_material_set_depth_range (CoglMaterial *material,
float near_val,
float far_val,
cogl_material_set_depth_state (CoglMaterial *material,
const CoglDepthState *state,
GError **error);
/**
* cogl_material_get_depth_range_mapping:
* cogl_material_get_depth_state
* @material: A #CoglMaterial object
* @near_val: A pointer to store the near component of the depth range
* @far_val: A pointer to store the far component of the depth range
* @state: A destination #CoglDepthState struct
*
* 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().
* Retrieves the current depth state configuration for the given
* @pipeline as previously set using cogl_pipeline_set_depth_state().
*
* Since: 1.4
* Since: 2.0
* Stability: Unstable
*/
void
cogl_material_get_depth_range (CoglMaterial *material,
float *near_val,
float *far_val);
cogl_material_get_depth_state (CoglMaterial *material,
CoglDepthState *state_out);
/**
* CoglMaterialLayerCallback:

View File

@ -445,36 +445,36 @@ blend_factor_uses_constant (GLenum blend_factor)
#endif
static void
flush_depth_state (CoglPipelineDepthState *depth_state)
flush_depth_state (CoglDepthState *depth_state)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->depth_test_function_cache != depth_state->depth_test_function)
if (ctx->depth_test_function_cache != depth_state->test_function)
{
GE (glDepthFunc (depth_state->depth_test_function));
ctx->depth_test_function_cache = depth_state->depth_test_function;
GE (glDepthFunc (depth_state->test_function));
ctx->depth_test_function_cache = depth_state->test_function;
}
if (ctx->depth_writing_enabled_cache != depth_state->depth_writing_enabled)
if (ctx->depth_writing_enabled_cache != depth_state->write_enabled)
{
GE (glDepthMask (depth_state->depth_writing_enabled ?
GE (glDepthMask (depth_state->write_enabled ?
GL_TRUE : GL_FALSE));
ctx->depth_writing_enabled_cache = depth_state->depth_writing_enabled;
ctx->depth_writing_enabled_cache = depth_state->write_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)
if (ctx->depth_range_near_cache != depth_state->range_near ||
ctx->depth_range_far_cache != depth_state->range_far)
{
#ifdef COGL_HAS_GLES2
GE (glDepthRangef (depth_state->depth_range_near,
depth_state->depth_range_far));
GE (glDepthRangef (depth_state->range_near,
depth_state->range_far));
#else
GE (glDepthRange (depth_state->depth_range_near,
depth_state->depth_range_far));
GE (glDepthRange (depth_state->range_near,
depth_state->range_far));
#endif
ctx->depth_range_near_cache = depth_state->depth_range_near;
ctx->depth_range_far_cache = depth_state->depth_range_far;
ctx->depth_range_near_cache = depth_state->range_near;
ctx->depth_range_far_cache = depth_state->range_far;
}
#endif /* COGL_HAS_GLES */
}
@ -609,21 +609,21 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
{
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH);
CoglPipelineDepthState *depth_state = &authority->big_state->depth_state;
CoglDepthState *depth_state = &authority->big_state->depth_state;
if (depth_state->depth_test_enabled)
if (depth_state->test_enabled)
{
if (ctx->depth_test_enabled_cache != TRUE)
{
GE (glEnable (GL_DEPTH_TEST));
ctx->depth_test_enabled_cache = depth_state->depth_test_enabled;
ctx->depth_test_enabled_cache = depth_state->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;
ctx->depth_test_enabled_cache = depth_state->test_enabled;
}
}

View File

@ -562,15 +562,6 @@ typedef struct
GLint blend_dst_factor_rgb;
} CoglPipelineBlendState;
typedef struct
{
gboolean depth_test_enabled;
CoglDepthTestFunction depth_test_function;
gboolean depth_writing_enabled;
float depth_range_near;
float depth_range_far;
} CoglPipelineDepthState;
typedef struct
{
gboolean enabled;
@ -587,7 +578,7 @@ typedef struct
CoglPipelineAlphaFuncState alpha_state;
CoglPipelineBlendState blend_state;
CoglHandle user_program;
CoglPipelineDepthState depth_state;
CoglDepthState depth_state;
CoglPipelineFogState fog_state;
float point_size;
} CoglPipelineBigState;

View File

@ -43,6 +43,7 @@
#include "cogl-color-private.h"
#include "cogl-util.h"
#include "cogl-profile.h"
#include "cogl-depth-state-private.h"
#include <glib.h>
#include <glib/gprintf.h>
@ -210,7 +211,7 @@ _cogl_pipeline_init_default_pipeline (void)
CoglPipelineLightingState *lighting_state = &big_state->lighting_state;
CoglPipelineAlphaFuncState *alpha_state = &big_state->alpha_state;
CoglPipelineBlendState *blend_state = &big_state->blend_state;
CoglPipelineDepthState *depth_state = &big_state->depth_state;
CoglDepthState *depth_state = &big_state->depth_state;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -308,11 +309,11 @@ _cogl_pipeline_init_default_pipeline (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;
depth_state->test_enabled = FALSE;
depth_state->test_function = COGL_DEPTH_TEST_FUNCTION_LESS;
depth_state->write_enabled = TRUE;
depth_state->range_near = 0;
depth_state->range_far = 1;
big_state->point_size = 1.0f;
@ -1074,7 +1075,7 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
{
memcpy (&big_state->depth_state,
&src->big_state->depth_state,
sizeof (CoglPipelineDepthState));
sizeof (CoglDepthState));
}
if (differences & COGL_PIPELINE_STATE_FOG)
@ -1147,7 +1148,7 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline,
{
memcpy (&pipeline->big_state->depth_state,
&authority->big_state->depth_state,
sizeof (CoglPipelineDepthState));
sizeof (CoglDepthState));
break;
}
case COGL_PIPELINE_STATE_FOG:
@ -3479,13 +3480,19 @@ static gboolean
_cogl_pipeline_depth_state_equal (CoglPipeline *authority0,
CoglPipeline *authority1)
{
if (authority0->big_state->depth_state.depth_test_enabled == FALSE &&
authority1->big_state->depth_state.depth_test_enabled == FALSE)
if (authority0->big_state->depth_state.test_enabled == FALSE &&
authority1->big_state->depth_state.test_enabled == FALSE)
return TRUE;
else
return memcmp (&authority0->big_state->depth_state,
&authority1->big_state->depth_state,
sizeof (CoglPipelineDepthState)) == 0;
{
CoglDepthState *s0 = &authority0->big_state->depth_state;
CoglDepthState *s1 = &authority1->big_state->depth_state;
return s0->test_enabled == s1->test_enabled &&
s0->test_function == s1->test_function &&
s0->write_enabled == s1->write_enabled &&
s0->range_near == s1->range_near &&
s0->range_far == s1->range_far;
}
}
static gboolean
@ -4703,154 +4710,40 @@ cogl_pipeline_set_user_program (CoglPipeline *pipeline,
handle_automatic_blend_enable (pipeline, state);
}
void
cogl_pipeline_set_depth_test_enabled (CoglPipeline *pipeline,
gboolean enable)
{
CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH;
CoglPipeline *authority;
CoglPipelineDepthState *depth_state;
g_return_if_fail (cogl_is_pipeline (pipeline));
authority = _cogl_pipeline_get_authority (pipeline, 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 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->depth_state.depth_test_enabled = enable;
_cogl_pipeline_update_authority (pipeline, authority, state,
_cogl_pipeline_depth_state_equal);
}
gboolean
cogl_pipeline_get_depth_test_enabled (CoglPipeline *pipeline)
{
CoglPipeline *authority;
g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE);
authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH);
return authority->big_state->depth_state.depth_test_enabled;
}
void
cogl_pipeline_set_depth_writing_enabled (CoglPipeline *pipeline,
gboolean enable)
{
CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH;
CoglPipeline *authority;
CoglPipelineDepthState *depth_state;
g_return_if_fail (cogl_is_pipeline (pipeline));
authority = _cogl_pipeline_get_authority (pipeline, 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 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->depth_state.depth_writing_enabled = enable;
_cogl_pipeline_update_authority (pipeline, authority, state,
_cogl_pipeline_depth_state_equal);
}
gboolean
cogl_pipeline_get_depth_writing_enabled (CoglPipeline *pipeline)
{
CoglPipeline *authority;
g_return_val_if_fail (cogl_is_pipeline (pipeline), TRUE);
authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH);
return authority->big_state->depth_state.depth_writing_enabled;
}
void
cogl_pipeline_set_depth_test_function (CoglPipeline *pipeline,
CoglDepthTestFunction function)
{
CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH;
CoglPipeline *authority;
CoglPipelineDepthState *depth_state;
g_return_if_fail (cogl_is_pipeline (pipeline));
authority = _cogl_pipeline_get_authority (pipeline, 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 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->depth_state.depth_test_function = function;
_cogl_pipeline_update_authority (pipeline, authority, state,
_cogl_pipeline_depth_state_equal);
}
CoglDepthTestFunction
cogl_pipeline_get_depth_test_function (CoglPipeline *pipeline)
{
CoglPipeline *authority;
g_return_val_if_fail (cogl_is_pipeline (pipeline),
COGL_DEPTH_TEST_FUNCTION_LESS);
authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH);
return authority->big_state->depth_state.depth_test_function;
}
gboolean
cogl_pipeline_set_depth_range (CoglPipeline *pipeline,
float near_val,
float far_val,
cogl_pipeline_set_depth_state (CoglPipeline *pipeline,
const CoglDepthState *depth_state,
GError **error)
{
#ifndef COGL_HAS_GLES
CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH;
CoglPipeline *authority;
CoglPipelineDepthState *depth_state;
CoglDepthState *orig_state;
g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE);
g_return_val_if_fail (cogl_is_pipeline (pipeline), TRUE);
g_return_if_fail (depth_state->magic == COGL_DEPTH_STATE_MAGIC);
authority = _cogl_pipeline_get_authority (pipeline, state);
depth_state = &authority->big_state->depth_state;
if (depth_state->depth_range_near == near_val &&
depth_state->depth_range_far == far_val)
orig_state = &authority->big_state->depth_state;
if (orig_state->test_enabled == depth_state->test_enabled &&
orig_state->write_enabled == depth_state->write_enabled &&
orig_state->test_function == depth_state->test_function &&
orig_state->range_near == depth_state->range_near &&
orig_state->range_far == depth_state->range_far)
return TRUE;
#ifdef COGL_HAS_GLES
if (depth_state->range_near != 0 ||
depth_state->range_far != 1)
{
g_set_error (error,
COGL_ERROR,
COGL_ERROR_UNSUPPORTED,
"glDepthRange not available on GLES 1");
return FALSE;
}
#endif
/* - 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
@ -4858,25 +4751,17 @@ cogl_pipeline_set_depth_range (CoglPipeline *pipeline,
*/
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
pipeline->big_state->depth_state.depth_range_near = near_val;
pipeline->big_state->depth_state.depth_range_far = far_val;
pipeline->big_state->depth_state = *depth_state;
_cogl_pipeline_update_authority (pipeline, authority, state,
_cogl_pipeline_depth_state_equal);
return TRUE;
#else
g_set_error (error,
COGL_ERROR,
COGL_ERROR_UNSUPPORTED,
"glDepthRange not available on GLES 1");
return FALSE;
#endif
}
void
cogl_pipeline_get_depth_range (CoglPipeline *pipeline,
float *near_val,
float *far_val)
cogl_pipeline_get_depth_state (CoglPipeline *pipeline,
CoglDepthState *state)
{
CoglPipeline *authority;
@ -4884,9 +4769,7 @@ cogl_pipeline_get_depth_range (CoglPipeline *pipeline,
authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH);
*near_val = authority->big_state->depth_state.depth_range_near;
*far_val = authority->big_state->depth_state.depth_range_far;
*state = authority->big_state->depth_state;
}
static void
@ -5880,7 +5763,12 @@ _cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline)
cogl_pipeline_set_user_program (pipeline, ctx->current_program);
if (ctx->legacy_depth_test_enabled)
cogl_pipeline_set_depth_test_enabled (pipeline, TRUE);
{
CoglDepthState depth_state;
cogl_depth_state_init (&depth_state);
cogl_depth_state_set_test_enabled (&depth_state, TRUE);
cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);
}
if (ctx->legacy_fog_state.enabled)
_cogl_pipeline_set_fog_state (pipeline, &ctx->legacy_fog_state);
@ -6277,22 +6165,22 @@ static void
_cogl_pipeline_hash_depth_state (CoglPipeline *authority,
HashState *state)
{
CoglPipelineDepthState *depth_state = &authority->big_state->depth_state;
CoglDepthState *depth_state = &authority->big_state->depth_state;
unsigned int hash = state->hash;
if (depth_state->depth_test_enabled)
if (depth_state->test_enabled)
{
guint8 enabled = depth_state->depth_test_enabled;
CoglDepthTestFunction function = depth_state->depth_test_function;
guint8 enabled = depth_state->test_enabled;
CoglDepthTestFunction function = depth_state->test_function;
hash = _cogl_util_one_at_a_time_hash (hash, &enabled, sizeof (enabled));
hash = _cogl_util_one_at_a_time_hash (hash, &function, sizeof (function));
}
if (depth_state->depth_writing_enabled)
if (depth_state->write_enabled)
{
guint8 enabled = depth_state->depth_writing_enabled;
float near_val = depth_state->depth_range_near;
float far_val = depth_state->depth_range_far;
guint8 enabled = depth_state->write_enabled;
float near_val = depth_state->range_near;
float far_val = depth_state->range_far;
hash = _cogl_util_one_at_a_time_hash (hash, &enabled, sizeof (enabled));
hash = _cogl_util_one_at_a_time_hash (hash, &near_val, sizeof (near_val));
hash = _cogl_util_one_at_a_time_hash (hash, &far_val, sizeof (far_val));

View File

@ -1054,167 +1054,44 @@ cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline,
#ifdef COGL_ENABLE_EXPERIMENTAL_API
/**
* cogl_pipeline_set_depth_test_enabled:
* cogl_pipeline_set_depth_state:
* @pipeline: A #CoglPipeline object
* @enable: The enable state you want
* @state: A #CoglDepthState struct
* @error: A #GError to report failures to setup the given @state.
*
* Enables or disables depth testing according to the value of
* @enable.
* This commits all the depth state configured in @state struct to the
* given @pipeline. The configuration values are copied into the
* pipeline so there is no requirement to keep the #CoglDepthState
* struct around if you don't need it any more.
*
* If depth testing is enable then the #CoglDepthTestFunction set
* using cogl_pipeline_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_pipeline_set_depth_writing_enabled ())
* Note: Since some platforms do not support the depth range feature
* it is possible for this function to fail and report an @error.
*
* By default depth testing is disabled.
*
* Since: 2.0
* Stability: Unstable
*/
void
cogl_pipeline_set_depth_test_enabled (CoglPipeline *pipeline,
gboolean enable);
/**
* cogl_pipeline_get_depth_test_enabled:
* @pipeline: A #CoglPipeline object
*
* Gets the current depth test enabled state as previously set by
* cogl_pipeline_set_depth_test_enabled().
*
* Returns: The pipeline's current depth test enabled state.
* Since: 2.0
* Stability: Unstable
*/
gboolean
cogl_pipeline_get_depth_test_enabled (CoglPipeline *pipeline);
/**
* cogl_pipeline_set_depth_writing_enabled:
* @pipeline: A #CoglPipeline object
* @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: 2.0
* Stability: Unstable
*/
void
cogl_pipeline_set_depth_writing_enabled (CoglPipeline *pipeline,
gboolean enable);
/**
* cogl_pipeline_get_depth_writing_enabled:
* @pipeline: A #CoglPipeline object
*
* Gets the depth writing enable state as set by the corresponding
* cogl_pipeline_set_depth_writing_enabled.
*
* Returns: The current depth writing enable state
* Since: 2.0
* Stability: Unstable
*/
gboolean
cogl_pipeline_get_depth_writing_enabled (CoglPipeline *pipeline);
/**
* cogl_pipeline_set_depth_test_function:
* @pipeline: A #CoglPipeline object
* @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: 2.0
* Stability: Unstable
*/
void
cogl_pipeline_set_depth_test_function (CoglPipeline *pipeline,
CoglDepthTestFunction function);
/**
* cogl_pipeline_get_depth_test_function:
* @pipeline: A #CoglPipeline object
*
* Gets the current depth test enable state as previously set via
* cogl_pipeline_set_depth_test_enabled().
*
* Returns: The current depth test enable state.
* Since: 2.0
* Stability: Unstable
*/
CoglDepthTestFunction
cogl_pipeline_get_depth_test_function (CoglPipeline *pipeline);
/**
* cogl_pipeline_set_depth_range:
* @pipeline: A #CoglPipeline object
* @near_val: The near component of the desired depth range which will be
* clamped to the range [0, 1]
* @far_val: 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.
* Returns: TRUE if the GPU supports all the given @state else %FALSE
* and returns an @error.
*
* Since: 2.0
* Stability: Unstable
*/
gboolean
cogl_pipeline_set_depth_range (CoglPipeline *pipeline,
float near_val,
float far_val,
cogl_pipeline_set_depth_state (CoglPipeline *pipeline,
const CoglDepthState *state,
GError **error);
/**
* cogl_pipeline_get_depth_range_mapping:
* cogl_pipeline_get_depth_state
* @pipeline: A #CoglPipeline object
* @near_val: A pointer to store the near component of the depth range
* @far_val: A pointer to store the far component of the depth range
* @state: A destination #CoglDepthState struct
*
* 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_pipeline_set_depth_range().
* Retrieves the current depth state configuration for the given
* @pipeline as previously set using cogl_pipeline_set_depth_state().
*
* Since: 2.0
* Stability: Unstable
*/
void
cogl_pipeline_get_depth_range (CoglPipeline *pipeline,
float *near_val,
float *far_val);
cogl_pipeline_get_depth_state (CoglPipeline *pipeline,
CoglDepthState *state_out);
/**
* CoglPipelineLayerCallback:

View File

@ -85,6 +85,7 @@ typedef struct _CoglFramebuffer CoglFramebuffer;
#include <cogl/cogl-indices.h>
#include <cogl/cogl-attribute.h>
#include <cogl/cogl-primitive.h>
#include <cogl/cogl-depth-state.h>
#include <cogl/cogl-pipeline.h>
#include <cogl/cogl-framebuffer.h>
#ifdef COGL_HAS_XLIB

View File

@ -190,7 +190,8 @@ _cogl_gl_update_features (CoglContext *context)
_cogl_get_gl_version (&gl_major, &gl_minor);
flags = (COGL_FEATURE_TEXTURE_READ_PIXELS
| COGL_FEATURE_UNSIGNED_INT_INDICES);
| COGL_FEATURE_UNSIGNED_INT_INDICES
| COGL_FEATURE_DEPTH_RANGE);
gl_extensions = (const char *)glGetString (GL_EXTENSIONS);

View File

@ -129,6 +129,7 @@ _cogl_gl_update_features (CoglContext *context)
/* Note GLES 2 core doesn't support mipmaps for npot textures or
* repeat modes other than CLAMP_TO_EDGE. */
flags |= COGL_FEATURE_TEXTURE_NPOT_BASIC;
flags |= COGL_FEATURE_DEPTH_RANGE;
#endif
flags |= COGL_FEATURE_VBOS;

View File

@ -68,6 +68,7 @@ IGNORE_HFILES=\
cogl-object-private.h \
cogl-path.h \
cogl-path-private.h \
cogl-depth-state-private.h \
cogl-pipeline-fragend-arbfp-private.h \
cogl-pipeline-fragend-fixed-private.h \
cogl-pipeline-fragend-glsl-private.h \

View File

@ -455,6 +455,20 @@ cogl_blend_string_error_get_type
cogl_blend_string_error_quark
</SECTION>
<SECTION>
<FILE>cogl-depth-state</FILE>
CoglDepthState
cogl_depth_state_init
cogl_depth_state_set_test_enabled
cogl_depth_state_get_test_enabled
cogl_depth_state_set_test_function
cogl_depth_state_get_test_function
cogl_depth_state_set_writing_enabled
cogl_depth_state_get_writing_enabled
cogl_depth_state_set_range
cogl_depth_state_get_range
</SECTION>
<SECTION>
<FILE>cogl-buffer</FILE>
<TITLE>CoglBuffer: The Base Buffer Type</TITLE>

View File

@ -66,6 +66,7 @@ IGNORE_HFILES=\
cogl-matrix-private.h \
cogl-object-private.h \
cogl-path-private.h \
cogl-depth-state-private.h \
cogl-pipeline-fragend-arbfp-private.h \
cogl-pipeline-fragend-fixed-private.h \
cogl-pipeline-fragend-glsl-private.h \

View File

@ -519,14 +519,6 @@ cogl_material_get_layer_wrap_mode_p
cogl_material_wrap_mode_get_type
cogl_material_set_user_program
cogl_material_get_user_program
cogl_material_set_depth_range
cogl_material_get_depth_range
cogl_material_set_depth_test_enabled
cogl_material_get_depth_test_enabled
cogl_material_set_depth_test_function
cogl_material_get_depth_test_function
cogl_material_set_depth_writing_enabled
cogl_material_get_depth_writing_enabled
cogl_material_foreach_layer
<SUBSECTION Private>
@ -534,6 +526,20 @@ cogl_blend_string_error_get_type
cogl_blend_string_error_quark
</SECTION>
<SECTION>
<FILE>cogl-depth-state</FILE>
CoglDepthState
cogl_depth_state_init
cogl_depth_state_set_test_enabled
cogl_depth_state_get_test_enabled
cogl_depth_state_set_test_function
cogl_depth_state_get_test_function
cogl_depth_state_set_writing_enabled
cogl_depth_state_get_writing_enabled
cogl_depth_state_set_range
cogl_depth_state_get_range
</SECTION>
<SECTION>
<FILE>cogl-buffer</FILE>
<TITLE>Buffers</TITLE>