deform-effect: Use CoglPipeline instead of setting legacy state
Instead of calling cogl_set_depth_test_enabled and cogl_set_backface_culling_enabled ClutterDeformEffect now uses the experimental CoglPipeline API. Those global state functions will soon be deprecated in Cogl and they are implemented by flushing a temporary override pipline which isn't ideal. Using the new culling API we can also avoid having a separate buffer of indices for the back of the texture by just changing the culling mode to cull front baces instead of the back. https://bugzilla.gnome.org/show_bug.cgi?id=663636
This commit is contained in:
parent
8a752d674b
commit
58b6ad787b
@ -76,10 +76,7 @@ struct _ClutterDeformEffectPrivate
|
||||
|
||||
CoglAttributeBuffer *buffer;
|
||||
|
||||
/* These two primitives use the same attributes but with different
|
||||
indices */
|
||||
CoglPrimitive *front_primitive;
|
||||
CoglPrimitive *back_primitive;
|
||||
CoglPrimitive *primitive;
|
||||
|
||||
CoglPrimitive *lines_primitive;
|
||||
|
||||
@ -173,8 +170,9 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect)
|
||||
{
|
||||
ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
|
||||
ClutterDeformEffectPrivate *priv = self->priv;
|
||||
gboolean is_depth_enabled, is_cull_enabled;
|
||||
CoglHandle material;
|
||||
CoglPipeline *pipeline;
|
||||
CoglDepthState depth_state;
|
||||
|
||||
if (priv->is_dirty)
|
||||
{
|
||||
@ -271,47 +269,46 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect)
|
||||
priv->is_dirty = FALSE;
|
||||
}
|
||||
|
||||
/* enable depth test, if it's not already enabled */
|
||||
is_depth_enabled = cogl_get_depth_test_enabled ();
|
||||
if (!is_depth_enabled)
|
||||
cogl_set_depth_test_enabled (TRUE);
|
||||
material = clutter_offscreen_effect_get_target (effect);
|
||||
pipeline = COGL_PIPELINE (material);
|
||||
|
||||
/* enable backface culling if it's not already enabled and if
|
||||
* we have a back material
|
||||
*/
|
||||
is_cull_enabled = cogl_get_backface_culling_enabled ();
|
||||
if (priv->back_material != COGL_INVALID_HANDLE && !is_cull_enabled)
|
||||
cogl_set_backface_culling_enabled (TRUE);
|
||||
else if (priv->back_material == COGL_INVALID_HANDLE && is_cull_enabled)
|
||||
cogl_set_backface_culling_enabled (FALSE);
|
||||
/* enable depth testing */
|
||||
cogl_depth_state_init (&depth_state);
|
||||
cogl_depth_state_set_test_enabled (&depth_state, TRUE);
|
||||
cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);
|
||||
|
||||
/* enable backface culling if we have a back material */
|
||||
if (priv->back_material != COGL_INVALID_HANDLE)
|
||||
cogl_pipeline_set_cull_face_mode (pipeline,
|
||||
COGL_PIPELINE_CULL_FACE_MODE_BACK);
|
||||
|
||||
/* draw the front */
|
||||
material = clutter_offscreen_effect_get_target (effect);
|
||||
if (material != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_push_source (material);
|
||||
cogl_primitive_draw (priv->front_primitive);
|
||||
cogl_push_source (pipeline);
|
||||
cogl_primitive_draw (priv->primitive);
|
||||
cogl_pop_source ();
|
||||
}
|
||||
|
||||
/* draw the back */
|
||||
material = priv->back_material;
|
||||
if (material != COGL_INVALID_HANDLE)
|
||||
if (priv->back_material != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_push_source (material);
|
||||
cogl_primitive_draw (priv->back_primitive);
|
||||
CoglPipeline *back_pipeline;
|
||||
|
||||
/* We probably shouldn't be modifying the user's material so
|
||||
instead we make a temporary copy */
|
||||
back_pipeline = cogl_pipeline_copy (priv->back_material);
|
||||
cogl_pipeline_set_depth_state (back_pipeline, &depth_state, NULL);
|
||||
cogl_pipeline_set_cull_face_mode (pipeline,
|
||||
COGL_PIPELINE_CULL_FACE_MODE_FRONT);
|
||||
|
||||
cogl_push_source (back_pipeline);
|
||||
cogl_primitive_draw (priv->primitive);
|
||||
cogl_pop_source ();
|
||||
|
||||
cogl_object_unref (back_pipeline);
|
||||
}
|
||||
|
||||
/* restore the previous state */
|
||||
if (!is_depth_enabled)
|
||||
cogl_set_depth_test_enabled (FALSE);
|
||||
|
||||
if (priv->back_material != COGL_INVALID_HANDLE && !is_cull_enabled)
|
||||
cogl_set_backface_culling_enabled (FALSE);
|
||||
else if (priv->back_material == COGL_INVALID_HANDLE && is_cull_enabled)
|
||||
cogl_set_backface_culling_enabled (TRUE);
|
||||
|
||||
if (G_UNLIKELY (priv->lines_primitive != NULL))
|
||||
{
|
||||
cogl_set_source_color4f (1.0, 0, 0, 1.0);
|
||||
@ -330,16 +327,10 @@ clutter_deform_effect_free_arrays (ClutterDeformEffect *self)
|
||||
priv->buffer = NULL;
|
||||
}
|
||||
|
||||
if (priv->front_primitive)
|
||||
if (priv->primitive)
|
||||
{
|
||||
cogl_object_unref (priv->front_primitive);
|
||||
priv->front_primitive = NULL;
|
||||
}
|
||||
|
||||
if (priv->back_primitive)
|
||||
{
|
||||
cogl_object_unref (priv->back_primitive);
|
||||
priv->back_primitive = NULL;
|
||||
cogl_object_unref (priv->primitive);
|
||||
priv->primitive = NULL;
|
||||
}
|
||||
|
||||
if (priv->lines_primitive)
|
||||
@ -353,11 +344,11 @@ static void
|
||||
clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv = self->priv;
|
||||
guint16 *static_front_indices, *static_back_indices;
|
||||
CoglIndices *front_indices, *back_indices;
|
||||
CoglAttribute *attributes[3];
|
||||
guint16 *front_idx, *back_idx;
|
||||
gint x, y, direction, n_indices;
|
||||
CoglAttribute *attributes[3];
|
||||
guint16 *static_indices;
|
||||
CoglIndices *indices;
|
||||
guint16 *idx;
|
||||
int i;
|
||||
|
||||
clutter_deform_effect_free_arrays (self);
|
||||
@ -366,23 +357,17 @@ clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
|
||||
* priv->y_tiles
|
||||
+ (priv->y_tiles - 1));
|
||||
|
||||
static_front_indices = g_new (guint16, n_indices);
|
||||
static_back_indices = g_new (guint16, n_indices);
|
||||
static_indices = g_new (guint16, n_indices);
|
||||
|
||||
#define MESH_INDEX(x,y) ((y) * (priv->x_tiles + 1) + (x))
|
||||
|
||||
/* compute all the triangles from the various tiles */
|
||||
direction = 1;
|
||||
|
||||
front_idx = static_front_indices;
|
||||
front_idx[0] = MESH_INDEX (0, 0);
|
||||
front_idx[1] = MESH_INDEX (0, 1);
|
||||
front_idx += 2;
|
||||
|
||||
back_idx = static_back_indices;
|
||||
back_idx[0] = MESH_INDEX (priv->x_tiles, 0);
|
||||
back_idx[1] = MESH_INDEX (priv->x_tiles, 1);
|
||||
back_idx += 2;
|
||||
idx = static_indices;
|
||||
idx[0] = MESH_INDEX (0, 0);
|
||||
idx[1] = MESH_INDEX (0, 1);
|
||||
idx += 2;
|
||||
|
||||
for (y = 0; y < priv->y_tiles; y++)
|
||||
{
|
||||
@ -390,23 +375,16 @@ clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
|
||||
{
|
||||
if (direction)
|
||||
{
|
||||
front_idx[0] = MESH_INDEX (x + 1, y);
|
||||
front_idx[1] = MESH_INDEX (x + 1, y + 1);
|
||||
|
||||
back_idx[0] = MESH_INDEX (priv->x_tiles - (x + 1), y);
|
||||
back_idx[1] = MESH_INDEX (priv->x_tiles - (x + 1), y + 1);
|
||||
idx[0] = MESH_INDEX (x + 1, y);
|
||||
idx[1] = MESH_INDEX (x + 1, y + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
front_idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y);
|
||||
front_idx[1] = MESH_INDEX (priv->x_tiles - x - 1, y + 1);
|
||||
|
||||
back_idx[0] = MESH_INDEX (x + 1, y);
|
||||
back_idx[1] = MESH_INDEX (x + 1, y + 1);
|
||||
idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y);
|
||||
idx[1] = MESH_INDEX (priv->x_tiles - x - 1, y + 1);
|
||||
}
|
||||
|
||||
front_idx += 2;
|
||||
back_idx += 2;
|
||||
idx += 2;
|
||||
}
|
||||
|
||||
if (y == (priv->y_tiles - 1))
|
||||
@ -414,42 +392,29 @@ clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
|
||||
|
||||
if (direction)
|
||||
{
|
||||
front_idx[0] = MESH_INDEX (priv->x_tiles, y + 1);
|
||||
front_idx[1] = MESH_INDEX (priv->x_tiles, y + 1);
|
||||
front_idx[2] = MESH_INDEX (priv->x_tiles, y + 2);
|
||||
|
||||
back_idx[0] = MESH_INDEX (0, y + 1);
|
||||
back_idx[1] = MESH_INDEX (0, y + 1);
|
||||
back_idx[2] = MESH_INDEX (0, y + 2);
|
||||
idx[0] = MESH_INDEX (priv->x_tiles, y + 1);
|
||||
idx[1] = MESH_INDEX (priv->x_tiles, y + 1);
|
||||
idx[2] = MESH_INDEX (priv->x_tiles, y + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
front_idx[0] = MESH_INDEX (0, y + 1);
|
||||
front_idx[1] = MESH_INDEX (0, y + 1);
|
||||
front_idx[2] = MESH_INDEX (0, y + 2);
|
||||
|
||||
back_idx[0] = MESH_INDEX (priv->x_tiles, y + 1);
|
||||
back_idx[1] = MESH_INDEX (priv->x_tiles, y + 1);
|
||||
back_idx[2] = MESH_INDEX (priv->x_tiles, y + 2);
|
||||
idx[0] = MESH_INDEX (0, y + 1);
|
||||
idx[1] = MESH_INDEX (0, y + 1);
|
||||
idx[2] = MESH_INDEX (0, y + 2);
|
||||
}
|
||||
|
||||
front_idx += 3;
|
||||
back_idx += 3;
|
||||
idx += 3;
|
||||
|
||||
direction = !direction;
|
||||
}
|
||||
|
||||
#undef MESH_INDEX
|
||||
|
||||
front_indices = cogl_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
|
||||
static_front_indices,
|
||||
n_indices);
|
||||
back_indices = cogl_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
|
||||
static_back_indices,
|
||||
indices = cogl_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
|
||||
static_indices,
|
||||
n_indices);
|
||||
|
||||
g_free (static_front_indices);
|
||||
g_free (static_back_indices);
|
||||
g_free (static_indices);
|
||||
|
||||
priv->n_vertices = (priv->x_tiles + 1) * (priv->y_tiles + 1);
|
||||
|
||||
@ -482,22 +447,13 @@ clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
|
||||
4, /* n_components */
|
||||
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
|
||||
|
||||
priv->front_primitive =
|
||||
priv->primitive =
|
||||
cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP,
|
||||
priv->n_vertices,
|
||||
attributes,
|
||||
3 /* n_attributes */);
|
||||
cogl_primitive_set_indices (priv->front_primitive,
|
||||
front_indices,
|
||||
n_indices);
|
||||
|
||||
priv->back_primitive =
|
||||
cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP,
|
||||
priv->n_vertices,
|
||||
attributes,
|
||||
3 /* n_attributes */);
|
||||
cogl_primitive_set_indices (priv->back_primitive,
|
||||
back_indices,
|
||||
cogl_primitive_set_indices (priv->primitive,
|
||||
indices,
|
||||
n_indices);
|
||||
|
||||
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DEFORM_TILES))
|
||||
@ -508,12 +464,11 @@ clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
|
||||
attributes,
|
||||
2 /* n_attributes */);
|
||||
cogl_primitive_set_indices (priv->lines_primitive,
|
||||
front_indices,
|
||||
indices,
|
||||
n_indices);
|
||||
}
|
||||
|
||||
cogl_object_unref (front_indices);
|
||||
cogl_object_unref (back_indices);
|
||||
cogl_object_unref (indices);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
cogl_object_unref (attributes[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user