static void clutter_deform_effect_finalize (GObject *gobject) { ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (gobject); clutter_deform_effect_free_arrays (self); clutter_deform_effect_free_back_pipeline (self); G_OBJECT_CLASS (clutter_deform_effect_parent_class)->finalize (gobject); }
static void clutter_deform_effect_init_arrays (ClutterDeformEffect *self) { ClutterDeformEffectPrivate *priv = self->priv; gint x, y, direction, n_indices; CoglAttribute *attributes[3]; guint16 *static_indices; CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); CoglIndices *indices; guint16 *idx; int i; clutter_deform_effect_free_arrays (self); n_indices = ((2 + 2 * priv->x_tiles) * priv->y_tiles + (priv->y_tiles - 1)); 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; 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++) { for (x = 0; x < priv->x_tiles; x++) { if (direction) { idx[0] = MESH_INDEX (x + 1, y); idx[1] = MESH_INDEX (x + 1, y + 1); } else { idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y); idx[1] = MESH_INDEX (priv->x_tiles - x - 1, y + 1); } idx += 2; } if (y == (priv->y_tiles - 1)) break; if (direction) { 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 { idx[0] = MESH_INDEX (0, y + 1); idx[1] = MESH_INDEX (0, y + 1); idx[2] = MESH_INDEX (0, y + 2); } idx += 3; direction = !direction; } #undef MESH_INDEX indices = cogl_indices_new (ctx, COGL_INDICES_TYPE_UNSIGNED_SHORT, static_indices, n_indices); g_free (static_indices); priv->n_vertices = (priv->x_tiles + 1) * (priv->y_tiles + 1); priv->buffer = cogl_attribute_buffer_new (ctx, sizeof (CoglVertexP3T2C4) * priv->n_vertices, NULL); /* The application is expected to continuously modify the vertices so we should give a hint to Cogl about that */ cogl_buffer_set_update_hint (COGL_BUFFER (priv->buffer), COGL_BUFFER_UPDATE_HINT_DYNAMIC); attributes[0] = cogl_attribute_new (priv->buffer, "cogl_position_in", sizeof (CoglVertexP3T2C4), G_STRUCT_OFFSET (CoglVertexP3T2C4, x), 3, /* n_components */ COGL_ATTRIBUTE_TYPE_FLOAT); attributes[1] = cogl_attribute_new (priv->buffer, "cogl_tex_coord0_in", sizeof (CoglVertexP3T2C4), G_STRUCT_OFFSET (CoglVertexP3T2C4, s), 2, /* n_components */ COGL_ATTRIBUTE_TYPE_FLOAT); attributes[2] = cogl_attribute_new (priv->buffer, "cogl_color_in", sizeof (CoglVertexP3T2C4), G_STRUCT_OFFSET (CoglVertexP3T2C4, r), 4, /* n_components */ COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); priv->primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP, priv->n_vertices, attributes, 3 /* n_attributes */); cogl_primitive_set_indices (priv->primitive, indices, n_indices); if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DEFORM_TILES)) { priv->lines_primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_LINE_STRIP, priv->n_vertices, attributes, 2 /* n_attributes */); cogl_primitive_set_indices (priv->lines_primitive, indices, n_indices); } cogl_object_unref (indices); for (i = 0; i < 3; i++) cogl_object_unref (attributes[i]); priv->is_dirty = TRUE; }
static void clutter_deform_effect_init_arrays (ClutterDeformEffect *self) { ClutterDeformEffectPrivate *priv = self->priv; GLushort *static_indices, *static_back_indices; GLushort *idx, *back_idx; gint x, y, direction; gint n_tiles; clutter_deform_effect_free_arrays (self); priv->n_indices = (2 + 2 * priv->x_tiles) * priv->y_tiles + (priv->y_tiles - 1); static_indices = g_new (GLushort, priv->n_indices); static_back_indices = g_new (GLushort, priv->n_indices); #define MESH_INDEX(x,y) ((y) * (priv->x_tiles + 1) + (x)) /* compute all the triangles from the various tiles */ direction = 1; idx = static_indices; idx[0] = MESH_INDEX (0, 0); idx[1] = MESH_INDEX (0, 1); 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; for (y = 0; y < priv->y_tiles; y++) { for (x = 0; x < priv->x_tiles; x++) { if (direction) { idx[0] = MESH_INDEX (x + 1, y); 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); } else { idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y); 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 += 2; back_idx += 2; } if (y == (priv->y_tiles - 1)) break; if (direction) { 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); back_idx[0] = MESH_INDEX (0, y + 1); back_idx[1] = MESH_INDEX (0, y + 1); back_idx[2] = MESH_INDEX (0, y + 2); } else { idx[0] = MESH_INDEX (0, y + 1); idx[1] = MESH_INDEX (0, y + 1); 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 += 3; back_idx += 3; direction = !direction; } #undef MESH_INDEX priv->indices = cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT, static_indices, priv->n_indices); priv->back_indices = cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT, static_back_indices, priv->n_indices); g_free (static_indices); g_free (static_back_indices); n_tiles = (priv->x_tiles + 1) * (priv->y_tiles + 1); priv->vertices = g_new (CoglTextureVertex, n_tiles); priv->vbo = cogl_vertex_buffer_new (n_tiles); priv->is_dirty = TRUE; }