mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
Merge branch 'wip/deform-effect'
* wip/deform-effect: docs: Add DeformEffect and PageTurnEffect to the API reference effect: Add PageTurnEffect effect: Add DeformEffect offscreen-effect: Traslate the modelview with the offsets docs: Fix Effect subclassing section
This commit is contained in:
commit
b8b2a51d44
@ -95,6 +95,7 @@ source_h = \
|
||||
$(srcdir)/clutter-colorize-effect.h \
|
||||
$(srcdir)/clutter-constraint.h \
|
||||
$(srcdir)/clutter-container.h \
|
||||
$(srcdir)/clutter-deform-effect.h \
|
||||
$(srcdir)/clutter-deprecated.h \
|
||||
$(srcdir)/clutter-desaturate-effect.h \
|
||||
$(srcdir)/clutter-device-manager.h \
|
||||
@ -117,6 +118,7 @@ source_h = \
|
||||
$(srcdir)/clutter-media.h \
|
||||
$(srcdir)/clutter-model.h \
|
||||
$(srcdir)/clutter-offscreen-effect.h \
|
||||
$(srcdir)/clutter-page-turn-effect.h \
|
||||
$(srcdir)/clutter-path.h \
|
||||
$(srcdir)/clutter-rectangle.h \
|
||||
$(srcdir)/clutter-score.h \
|
||||
@ -182,6 +184,7 @@ source_c = \
|
||||
$(srcdir)/clutter-colorize-effect.c \
|
||||
$(srcdir)/clutter-constraint.c \
|
||||
$(srcdir)/clutter-container.c \
|
||||
$(srcdir)/clutter-deform-effect.c \
|
||||
$(srcdir)/clutter-desaturate-effect.c \
|
||||
$(srcdir)/clutter-device-manager.c \
|
||||
$(srcdir)/clutter-drag-action.c \
|
||||
@ -205,6 +208,7 @@ source_c = \
|
||||
$(srcdir)/clutter-media.c \
|
||||
$(srcdir)/clutter-model.c \
|
||||
$(srcdir)/clutter-offscreen-effect.c \
|
||||
$(srcdir)/clutter-page-turn-effect.c \
|
||||
$(srcdir)/clutter-path.c \
|
||||
$(srcdir)/clutter-rectangle.c \
|
||||
$(srcdir)/clutter-score.c \
|
||||
|
739
clutter/clutter-deform-effect.c
Normal file
739
clutter/clutter-deform-effect.c
Normal file
@ -0,0 +1,739 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 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/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* Based on the MxDeformTexture class, written by:
|
||||
* Chris Lord <chris@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:clutter-deform-effect
|
||||
* @Title: ClutterDeformEffect
|
||||
* @Short_Description: A base class for effects deforming the geometry
|
||||
* of an actor
|
||||
*
|
||||
* #ClutterDeformEffect is an abstract class providing all the plumbing
|
||||
* for creating effects that result in the deformation of an actor's
|
||||
* geometry.
|
||||
*
|
||||
* #ClutterDeformEffect uses offscreen buffers to render the contents of
|
||||
* a #ClutterActor and then the Cogl vertex buffers API to submit the
|
||||
* geomtry to the GPU.
|
||||
*
|
||||
* <refsect2>
|
||||
* <title>Implementing ClutterDeformEffect</title>
|
||||
* <para>Sub-classes of #ClutterDeformEffect should override the
|
||||
* <function>deform_vertex()</function> virtual function; this function
|
||||
* is called on every vertex that needs to be deformed by the effect.
|
||||
* Each passed vertex is an in-out parameter that initially contains the
|
||||
* position of the vertex and should be modified according to a specific
|
||||
* deformation algorithm.</para>
|
||||
* </refsect2>
|
||||
*
|
||||
* #ClutterDeformEffect is available since Clutter 1.4
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "clutter-deform-effect.h"
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define DEFAULT_N_TILES 32
|
||||
|
||||
struct _ClutterDeformEffectPrivate
|
||||
{
|
||||
CoglHandle back_material;
|
||||
|
||||
gint x_tiles;
|
||||
gint y_tiles;
|
||||
|
||||
CoglHandle vbo;
|
||||
|
||||
CoglHandle indices;
|
||||
CoglHandle back_indices;
|
||||
gint n_indices;
|
||||
|
||||
CoglTextureVertex *vertices;
|
||||
|
||||
gulong allocation_id;
|
||||
|
||||
guint is_dirty : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_X_TILES,
|
||||
PROP_Y_TILES,
|
||||
|
||||
PROP_BACK_MATERIAL
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterDeformEffect,
|
||||
clutter_deform_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static void
|
||||
clutter_deform_effect_real_deform_vertex (ClutterDeformEffect *effect,
|
||||
gfloat width,
|
||||
gfloat height,
|
||||
CoglTextureVertex *vertex)
|
||||
{
|
||||
g_warning ("%s: Deformation effect of type '%s' does not implement "
|
||||
"the required ClutterDeformEffect::deform_vertex virtual "
|
||||
"function.",
|
||||
G_STRLOC,
|
||||
G_OBJECT_TYPE_NAME (effect));
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_deform_effect_deform_vertex (ClutterDeformEffect *effect,
|
||||
gfloat width,
|
||||
gfloat height,
|
||||
CoglTextureVertex *vertex)
|
||||
{
|
||||
CLUTTER_DEFORM_EFFECT_GET_CLASS (effect)->deform_vertex (effect,
|
||||
width, height,
|
||||
vertex);
|
||||
}
|
||||
|
||||
static void
|
||||
vbo_invalidate (ClutterActor *actor,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags,
|
||||
ClutterDeformEffect *effect)
|
||||
{
|
||||
effect->priv->is_dirty = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv = CLUTTER_DEFORM_EFFECT (meta)->priv;
|
||||
|
||||
if (priv->allocation_id != 0)
|
||||
{
|
||||
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
|
||||
|
||||
g_signal_handler_disconnect (old_actor, priv->allocation_id);
|
||||
priv->allocation_id = 0;
|
||||
}
|
||||
|
||||
/* we need to invalidate the VBO whenever the allocation of the actor
|
||||
* changes
|
||||
*/
|
||||
if (actor != NULL)
|
||||
priv->allocation_id = g_signal_connect (actor, "allocation-changed",
|
||||
G_CALLBACK (vbo_invalidate),
|
||||
meta);
|
||||
|
||||
priv->is_dirty = TRUE;
|
||||
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_deform_effect_parent_class)->set_actor (meta, actor);
|
||||
}
|
||||
|
||||
static void
|
||||
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;
|
||||
gint n_tiles;
|
||||
|
||||
if (priv->is_dirty)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
gfloat width, height;
|
||||
guint opacity;
|
||||
gint i, j;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
opacity = clutter_actor_get_paint_opacity (actor);
|
||||
clutter_actor_get_size (actor, &width, &height);
|
||||
|
||||
for (i = 0; i < priv->y_tiles + 1; i++)
|
||||
{
|
||||
for (j = 0; j < priv->x_tiles + 1; j++)
|
||||
{
|
||||
CoglTextureVertex *vertex;
|
||||
|
||||
vertex = &priv->vertices[(i * (priv->x_tiles + 1)) + j];
|
||||
|
||||
vertex->tx = (float) j / priv->x_tiles;
|
||||
vertex->ty = (float) i / priv->y_tiles;
|
||||
|
||||
vertex->x = width * vertex->tx;
|
||||
vertex->y = height * vertex->ty;
|
||||
vertex->z = 0.0f;
|
||||
|
||||
cogl_color_set_from_4ub (&vertex->color, 255, 255, 255, opacity);
|
||||
|
||||
_clutter_deform_effect_deform_vertex (self, width, height, vertex);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX in theory, the sub-classes should tell us what they changed
|
||||
* in the texture vertices; we then would be able to avoid resubmitting
|
||||
* the same data, if it did not change. for the time being, we resubmit
|
||||
* everything
|
||||
*/
|
||||
cogl_vertex_buffer_add (priv->vbo, "gl_Vertex",
|
||||
3,
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT,
|
||||
FALSE,
|
||||
sizeof (CoglTextureVertex),
|
||||
&priv->vertices->x);
|
||||
cogl_vertex_buffer_add (priv->vbo, "gl_MultiTexCoord0",
|
||||
2,
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT,
|
||||
FALSE,
|
||||
sizeof (CoglTextureVertex),
|
||||
&priv->vertices->tx);
|
||||
cogl_vertex_buffer_add (priv->vbo, "gl_Color",
|
||||
4,
|
||||
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE,
|
||||
FALSE,
|
||||
sizeof (CoglTextureVertex),
|
||||
&priv->vertices->color);
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
n_tiles = (priv->x_tiles + 1) * (priv->y_tiles + 1);
|
||||
|
||||
/* draw the front */
|
||||
material = clutter_offscreen_effect_get_target (effect);
|
||||
if (material != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_set_source (material);
|
||||
cogl_vertex_buffer_draw_elements (priv->vbo,
|
||||
COGL_VERTICES_MODE_TRIANGLE_STRIP,
|
||||
priv->indices,
|
||||
0,
|
||||
n_tiles,
|
||||
0,
|
||||
priv->n_indices);
|
||||
}
|
||||
|
||||
/* draw the back */
|
||||
material = priv->back_material;
|
||||
if (material != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_set_source (priv->back_material);
|
||||
cogl_vertex_buffer_draw_elements (priv->vbo,
|
||||
COGL_VERTICES_MODE_TRIANGLE_STRIP,
|
||||
priv->back_indices,
|
||||
0,
|
||||
n_tiles,
|
||||
0,
|
||||
priv->n_indices);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_deform_effect_free_arrays (ClutterDeformEffect *self)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv = self->priv;
|
||||
|
||||
if (priv->vbo != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_handle_unref (priv->vbo);
|
||||
priv->vbo = COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (priv->indices != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_handle_unref (priv->indices);
|
||||
priv->indices = COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
g_free (priv->vertices);
|
||||
priv->vertices = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_deform_effect_free_back_material (ClutterDeformEffect *self)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv = self->priv;
|
||||
|
||||
if (priv->back_material != NULL)
|
||||
{
|
||||
cogl_handle_unref (priv->back_material);
|
||||
priv->back_material = COGL_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
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_material (self);
|
||||
|
||||
G_OBJECT_CLASS (clutter_deform_effect_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_X_TILES:
|
||||
clutter_deform_effect_set_n_tiles (self, g_value_get_uint (value),
|
||||
self->priv->y_tiles);
|
||||
break;
|
||||
|
||||
case PROP_Y_TILES:
|
||||
clutter_deform_effect_set_n_tiles (self, self->priv->x_tiles,
|
||||
g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
case PROP_BACK_MATERIAL:
|
||||
clutter_deform_effect_set_back_material (self, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv = CLUTTER_DEFORM_EFFECT (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_X_TILES:
|
||||
g_value_set_uint (value, priv->x_tiles);
|
||||
break;
|
||||
|
||||
case PROP_Y_TILES:
|
||||
g_value_set_uint (value, priv->y_tiles);
|
||||
break;
|
||||
|
||||
case PROP_BACK_MATERIAL:
|
||||
g_value_set_boxed (value, priv->back_material);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_class_init (ClutterDeformEffectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
ClutterOffscreenEffectClass *offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (ClutterDeformEffectPrivate));
|
||||
|
||||
klass->deform_vertex = clutter_deform_effect_real_deform_vertex;
|
||||
|
||||
gobject_class->set_property = clutter_deform_effect_set_property;
|
||||
gobject_class->get_property = clutter_deform_effect_get_property;
|
||||
gobject_class->finalize = clutter_deform_effect_finalize;
|
||||
|
||||
/**
|
||||
* ClutterDeformEffect:x-tiles:
|
||||
*
|
||||
* The number of horizontal tiles. The bigger the number, the
|
||||
* smaller the tiles
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
pspec = g_param_spec_uint ("x-tiles",
|
||||
"Horiontal Tiles",
|
||||
"The number of horizontal tiles",
|
||||
1, G_MAXUINT,
|
||||
DEFAULT_N_TILES,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_X_TILES, pspec);
|
||||
|
||||
/**
|
||||
* ClutterDeformEffect:y-tiles:
|
||||
*
|
||||
* The number of vertical tiles. The bigger the number, the
|
||||
* smaller the tiles
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
pspec = g_param_spec_uint ("y-tiles",
|
||||
"Vertical Tiles",
|
||||
"The number of vertical tiles",
|
||||
1, G_MAXUINT,
|
||||
DEFAULT_N_TILES,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_Y_TILES, pspec);
|
||||
|
||||
/**
|
||||
* ClutterDeformEffect:back-material:
|
||||
*
|
||||
* A material to be used when painting the back of the actor
|
||||
* to which this effect has been applied
|
||||
*
|
||||
* By default, no material will be used
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
pspec = g_param_spec_boxed ("back-material",
|
||||
"Back Material",
|
||||
"The material to be used when painting the "
|
||||
"back of the actor",
|
||||
COGL_TYPE_HANDLE,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_BACK_MATERIAL, pspec);
|
||||
|
||||
meta_class->set_actor = clutter_deform_effect_set_actor;
|
||||
|
||||
offscreen_class->paint_target = clutter_deform_effect_paint_target;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_init (ClutterDeformEffect *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, CLUTTER_TYPE_DEFORM_EFFECT,
|
||||
ClutterDeformEffectPrivate);
|
||||
|
||||
self->priv->x_tiles = self->priv->y_tiles = DEFAULT_N_TILES;
|
||||
self->priv->back_material = COGL_INVALID_HANDLE;
|
||||
|
||||
clutter_deform_effect_init_arrays (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_set_back_material:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
* @material: (allow-none): a handle to a Cogl material
|
||||
*
|
||||
* Sets the material that should be used when drawing the back face
|
||||
* of the actor during a deformation
|
||||
*
|
||||
* The #ClutterDeformEffect will take a reference on the material's
|
||||
* handle
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_deform_effect_set_back_material (ClutterDeformEffect *effect,
|
||||
CoglHandle material)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
|
||||
g_return_if_fail (material == COGL_INVALID_HANDLE || cogl_is_material (material));
|
||||
|
||||
priv = effect->priv;
|
||||
|
||||
clutter_deform_effect_free_back_material (effect);
|
||||
|
||||
priv->back_material = material;
|
||||
if (priv->back_material != COGL_INVALID_HANDLE)
|
||||
cogl_handle_ref (priv->back_material);
|
||||
|
||||
clutter_deform_effect_invalidate (effect);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_get_back_material:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
*
|
||||
* Retrieves the handle to the back face material used by @effect
|
||||
*
|
||||
* Return value: (transfer none): a handle for the material, or %NULL.
|
||||
* The returned material is owned by the #ClutterDeformEffect and it
|
||||
* should not be freed directly
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
CoglHandle
|
||||
clutter_deform_effect_get_back_material (ClutterDeformEffect *effect)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect), NULL);
|
||||
|
||||
return effect->priv->back_material;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_set_n_tiles:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
* @x_tiles: number of horizontal tiles
|
||||
* @y_tiles: number of vertical tiles
|
||||
*
|
||||
* Sets the number of horizontal and vertical tiles to be used
|
||||
* when applying the effect
|
||||
*
|
||||
* More tiles allow a finer grained deformation at the expenses
|
||||
* of computation
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect,
|
||||
guint x_tiles,
|
||||
guint y_tiles)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv;
|
||||
gboolean tiles_changed = FALSE;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
|
||||
g_return_if_fail (x_tiles > 0 && y_tiles > 0);
|
||||
|
||||
priv = effect->priv;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (effect));
|
||||
|
||||
if (priv->x_tiles != x_tiles)
|
||||
{
|
||||
priv->x_tiles = x_tiles;
|
||||
|
||||
g_object_notify (G_OBJECT (effect), "x-tiles");
|
||||
|
||||
tiles_changed = TRUE;
|
||||
}
|
||||
|
||||
if (priv->y_tiles != y_tiles)
|
||||
{
|
||||
priv->y_tiles = y_tiles;
|
||||
|
||||
g_object_notify (G_OBJECT (effect), "y-tiles");
|
||||
|
||||
tiles_changed = TRUE;
|
||||
}
|
||||
|
||||
if (tiles_changed)
|
||||
{
|
||||
clutter_deform_effect_init_arrays (effect);
|
||||
clutter_deform_effect_invalidate (effect);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (effect));
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_get_n_tiles:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
* @x_tiles: (out): return location for the number of horizontal tiles,
|
||||
* or %NULL
|
||||
* @y_tiles: (out): return location for the number of vertical tiles,
|
||||
* or %NULL
|
||||
*
|
||||
* Retrieves the number of horizontal and vertical tiles used to sub-divide
|
||||
* the actor's geometry during the effect
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect,
|
||||
guint *x_tiles,
|
||||
guint *y_tiles)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
|
||||
|
||||
if (x_tiles != NULL)
|
||||
*x_tiles = effect->priv->x_tiles;
|
||||
|
||||
if (y_tiles != NULL)
|
||||
*y_tiles = effect->priv->y_tiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_invalidate:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
*
|
||||
* Invalidates the @effect<!-- -->'s vertices and, if it is associated
|
||||
* to an actor, it will queue a redraw
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_deform_effect_invalidate (ClutterDeformEffect *effect)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
|
||||
|
||||
if (effect->priv->is_dirty)
|
||||
return;
|
||||
|
||||
effect->priv->is_dirty = TRUE;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
if (actor != NULL)
|
||||
clutter_actor_queue_redraw (actor);
|
||||
}
|
111
clutter/clutter-deform-effect.h
Normal file
111
clutter/clutter-deform-effect.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 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/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __CLUTTER_DEFORM_EFFECT_H__
|
||||
#define __CLUTTER_DEFORM_EFFECT_H__
|
||||
|
||||
#include <clutter/clutter-color.h>
|
||||
#include <clutter/clutter-offscreen-effect.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_DEFORM_EFFECT (clutter_deform_effect_get_type ())
|
||||
#define CLUTTER_DEFORM_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEFORM_EFFECT, ClutterDeformEffect))
|
||||
#define CLUTTER_IS_DEFORM_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEFORM_EFFECT))
|
||||
#define CLUTTER_DEFORM_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEFORM_EFFECT, ClutterDeformEffectClass))
|
||||
#define CLUTTER_IS_DEFORM_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEFORM_EFFECT))
|
||||
#define CLUTTER_DEFORM_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEFORM_EFFECT, ClutterDeformEffectClass))
|
||||
|
||||
typedef struct _ClutterDeformEffect ClutterDeformEffect;
|
||||
typedef struct _ClutterDeformEffectPrivate ClutterDeformEffectPrivate;
|
||||
typedef struct _ClutterDeformEffectClass ClutterDeformEffectClass;
|
||||
|
||||
/**
|
||||
* ClutterDeformEffect:
|
||||
*
|
||||
* The <structname>ClutterDeformEffect</structname> structure contains
|
||||
* only private data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterDeformEffect
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterOffscreenEffect parent_instance;
|
||||
|
||||
ClutterDeformEffectPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterDeformEffectClass:
|
||||
* @deform_vertex: virtual function; sub-classes should override this
|
||||
* function to compute the deformation of each vertex
|
||||
*
|
||||
* The <structname>ClutterDeformEffectClass</structname> structure contains
|
||||
* only private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterDeformEffectClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* deform_vertex) (ClutterDeformEffect *effect,
|
||||
gfloat width,
|
||||
gfloat height,
|
||||
CoglTextureVertex *vertex);
|
||||
|
||||
/*< private >*/
|
||||
void (*_clutter_deform1) (void);
|
||||
void (*_clutter_deform2) (void);
|
||||
void (*_clutter_deform3) (void);
|
||||
void (*_clutter_deform4) (void);
|
||||
void (*_clutter_deform5) (void);
|
||||
void (*_clutter_deform6) (void);
|
||||
void (*_clutter_deform7) (void);
|
||||
};
|
||||
|
||||
GType clutter_deform_effect_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void clutter_deform_effect_set_back_material (ClutterDeformEffect *effect,
|
||||
CoglHandle material);
|
||||
CoglHandle clutter_deform_effect_get_back_material (ClutterDeformEffect *effect);
|
||||
void clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect,
|
||||
guint x_tiles,
|
||||
guint y_tiles);
|
||||
void clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect,
|
||||
guint *x_tiles,
|
||||
guint *y_tiles);
|
||||
|
||||
void clutter_deform_effect_invalidate (ClutterDeformEffect *effect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_DEFORM_EFFECT_H__ */
|
@ -39,29 +39,17 @@
|
||||
* <refsect2 id="ClutterEffect-implementation">
|
||||
* <title>Implementing a ClutterEffect</title>
|
||||
* <para>Creating a sub-class of #ClutterEffect requires the implementation
|
||||
* of three virtual functions:</para>
|
||||
* of two virtual functions:</para>
|
||||
* <itemizedlist>
|
||||
* <listitem><simpara><function>prepare()</function>, which is called when
|
||||
* attaching the #ClutterEffect to a #ClutterActor through the
|
||||
* clutter_actor_add_effect() function or when the actor is being
|
||||
* painted;</simpara></listitem>
|
||||
* <listitem><simpara><function>pre_paint()</function>, which is called
|
||||
* before painting the #ClutterActor.</simpara></listitem>
|
||||
* <listitem><simpara><function>post_paint()</function>, which is called
|
||||
* after painting the #ClutterActor.</simpara></listitem>
|
||||
* </itemizedlist>
|
||||
* <para>The <function>prepare()</function> function receives the
|
||||
* #ClutterActor to which the effect has been attached to, and it should be
|
||||
* used to set up the initial state of the effect, for instance depending on
|
||||
* the actor that has been passed. The function returns a boolean value,
|
||||
* which is used to determine whether the #ClutterEffect has been prepared or
|
||||
* not. An unprepared shader will be asked to prepare itself again during the
|
||||
* actor's paint sequence, and if it fails again it will be ignored.</para>
|
||||
* <para>The <function>pre_paint()</function> function should be used to set
|
||||
* up the #ClutterEffect right before the #ClutterActor's paint
|
||||
* sequence. This function, like <function>prepare()</function> can fail, and
|
||||
* return %FALSE; in that case, no <function>post_paint()</function>
|
||||
* invocation will follow.</para>
|
||||
* sequence. This function can fail, and return %FALSE; in that case, no
|
||||
* <function>post_paint()</function> invocation will follow.</para>
|
||||
* <para>The <function>post_paint()</function> function is called after the
|
||||
* #ClutterActor's paint sequence.</para>
|
||||
* <para>The <function>pre_paint()</function> phase could be seen as a custom
|
||||
@ -73,8 +61,8 @@
|
||||
* <title>A simple ClutterEffect implementation</title>
|
||||
* <para>The example below creates two rectangles: one will be painted
|
||||
* "behind" the actor, while another will be painted "on top" of the actor.
|
||||
* The <function>prepare()</function> phase will create the two materials
|
||||
* used for the two different rectangles; the
|
||||
* The <function>set_actor()</function> implementation will create the two
|
||||
* materials used for the two different rectangles; the
|
||||
* <function>pre_paint()</function> function will paint the first material
|
||||
* using cogl_rectangle(), while the <function>post_paint()</function>
|
||||
* phase will paint the second material.</para>
|
||||
|
@ -316,12 +316,12 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect)
|
||||
|
||||
/* paint the texture at the same position as the actor would be,
|
||||
* in Stage coordinates, since we set up the modelview matrix to
|
||||
* be exactly as the stage sets it up
|
||||
* be exactly as the stage sets it up, plus the eventual offsets
|
||||
* due to offscreen effects stacking
|
||||
*/
|
||||
cogl_rectangle_with_texture_coords (priv->x_offset,
|
||||
priv->y_offset,
|
||||
priv->x_offset + priv->target_width,
|
||||
priv->y_offset + priv->target_height,
|
||||
cogl_rectangle_with_texture_coords (0, 0,
|
||||
priv->target_width,
|
||||
priv->target_height,
|
||||
0.0, 0.0,
|
||||
1.0, 1.0);
|
||||
}
|
||||
@ -364,6 +364,8 @@ clutter_offscreen_effect_post_paint (ClutterEffect *effect)
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
cogl_translate (priv->x_offset, priv->y_offset, 0.0f);
|
||||
|
||||
/* paint the target material; this is virtualized for
|
||||
* sub-classes that require special hand-holding
|
||||
*/
|
||||
|
417
clutter/clutter-page-turn-effect.c
Normal file
417
clutter/clutter-page-turn-effect.c
Normal file
@ -0,0 +1,417 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 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/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* Based on MxDeformPageTurn, written by:
|
||||
* Chris Lord <chris@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:clutter-page-turn-effect
|
||||
* @Title: ClutterPageTurnEffect
|
||||
* @Short_Description: A page turning effect
|
||||
*
|
||||
* A simple page turning effect
|
||||
*
|
||||
* #ClutterPageTurnEffect is available since Clutter 1.4
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "clutter-page-turn-effect.h"
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define CLUTTER_PAGE_TURN_EFFECT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), CLUTTER_TYPE_PAGE_TURN_EFFECT, ClutterPageTurnEffectClass))
|
||||
#define CLUTTER_IS_PAGE_TURN_EFFECT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CLUTTER_TYPE_PAGE_TURN_EFFECT))
|
||||
#define CLUTTER_PAGE_TURN_EFFECT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CLUTTER_TYPE_PAGE_TURN_EFFECT, ClutterPageTurnEffectClass))
|
||||
|
||||
typedef struct _ClutterPageTurnEffectClass ClutterPageTurnEffectClass;
|
||||
|
||||
struct _ClutterPageTurnEffect
|
||||
{
|
||||
ClutterDeformEffect parent_instance;
|
||||
|
||||
gdouble period;
|
||||
gdouble angle;
|
||||
|
||||
gfloat radius;
|
||||
};
|
||||
|
||||
struct _ClutterPageTurnEffectClass
|
||||
{
|
||||
ClutterDeformEffectClass parent_class;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_PERIOD,
|
||||
PROP_ANGLE,
|
||||
PROP_RADIUS
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterPageTurnEffect,
|
||||
clutter_page_turn_effect,
|
||||
CLUTTER_TYPE_DEFORM_EFFECT);
|
||||
|
||||
static void
|
||||
clutter_page_turn_effect_deform_vertex (ClutterDeformEffect *effect,
|
||||
gfloat width,
|
||||
gfloat height,
|
||||
CoglTextureVertex *vertex)
|
||||
{
|
||||
ClutterPageTurnEffect *self = CLUTTER_PAGE_TURN_EFFECT (effect);
|
||||
gfloat cx, cy, rx, ry, radians, turn_angle;
|
||||
guint shade;
|
||||
|
||||
if (self->period == 0.0)
|
||||
return;
|
||||
|
||||
radians = self->angle * 180.0f / G_PI;
|
||||
|
||||
/* Rotate the point around the centre of the page-curl ray to align it with
|
||||
* the y-axis.
|
||||
*/
|
||||
cx = (1.f - self->period) * width;
|
||||
cy = (1.f - self->period) * height;
|
||||
|
||||
rx = ((vertex->x - cx) * cos (- radians))
|
||||
- ((vertex->y - cy) * sin (- radians))
|
||||
- self->radius;
|
||||
ry = ((vertex->x - cx) * sin (- radians))
|
||||
+ ((vertex->y - cy) * cos (- radians));
|
||||
|
||||
turn_angle = 0.f;
|
||||
if (rx > self->radius * -2.0f)
|
||||
{
|
||||
/* Calculate the curl angle as a function from the distance of the curl
|
||||
* ray (i.e. the page crease)
|
||||
*/
|
||||
turn_angle = (rx / self->radius * G_PI_2) - G_PI_2;
|
||||
shade = (sin (turn_angle) * 96.0f) + 159.0f;
|
||||
|
||||
/* Add a gradient that makes it look like lighting and hides the switch
|
||||
* between textures.
|
||||
*/
|
||||
cogl_color_set_from_4ub (&vertex->color, shade, shade, shade, 0xff);
|
||||
}
|
||||
|
||||
if (rx > 0)
|
||||
{
|
||||
/* Make the curl radius smaller as more circles are formed (stops
|
||||
* z-fighting and looks cool). Note that 10 is a semi-arbitrary
|
||||
* number here - divide it by two and it's the amount of space
|
||||
* between curled layers of the texture, in pixels.
|
||||
*/
|
||||
gfloat small_radius;
|
||||
|
||||
small_radius = self->radius
|
||||
- MIN (self->radius, (turn_angle * 10) / G_PI);
|
||||
|
||||
/* Calculate a point on a cylinder (maybe make this a cone at some
|
||||
* point) and rotate it by the specified angle.
|
||||
*/
|
||||
rx = (small_radius * cos (turn_angle)) + self->radius;
|
||||
|
||||
vertex->x = (rx * cos (radians)) - (ry * sin (radians)) + cx;
|
||||
vertex->y = (rx * sin (radians)) + (ry * cos (radians)) + cy;
|
||||
vertex->z = (small_radius * sin (turn_angle)) + self->radius;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_page_turn_effect_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterPageTurnEffect *effect = CLUTTER_PAGE_TURN_EFFECT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PERIOD:
|
||||
clutter_page_turn_effect_set_period (effect, g_value_get_double (value));
|
||||
break;
|
||||
|
||||
case PROP_ANGLE:
|
||||
clutter_page_turn_effect_set_angle (effect, g_value_get_double (value));
|
||||
break;
|
||||
|
||||
case PROP_RADIUS:
|
||||
clutter_page_turn_effect_set_radius (effect, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_page_turn_effect_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterPageTurnEffect *effect = CLUTTER_PAGE_TURN_EFFECT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PERIOD:
|
||||
g_value_set_double (value, effect->period);
|
||||
break;
|
||||
|
||||
case PROP_ANGLE:
|
||||
g_value_set_double (value, effect->angle);
|
||||
break;
|
||||
|
||||
case PROP_RADIUS:
|
||||
g_value_set_float (value, effect->radius);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_page_turn_effect_class_init (ClutterPageTurnEffectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterDeformEffectClass *deform_class = CLUTTER_DEFORM_EFFECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = clutter_page_turn_effect_set_property;
|
||||
gobject_class->get_property = clutter_page_turn_effect_get_property;
|
||||
|
||||
/**
|
||||
* ClutterPageTurnEffect:period:
|
||||
*
|
||||
* The period of the page turn, between 0.0 (no curling) and
|
||||
* 1.0 (fully curled)
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
pspec = g_param_spec_double ("period",
|
||||
"Period",
|
||||
"The period of the page turn",
|
||||
0.0, 1.0,
|
||||
0.0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_PERIOD, pspec);
|
||||
|
||||
/**
|
||||
* ClutterPageTurnEffect:angle:
|
||||
*
|
||||
* The angle of the page rotation, in degrees, between 0.0 and 360.0
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
pspec = g_param_spec_double ("angle",
|
||||
"Angle",
|
||||
"The angle of the page rotation, in degrees",
|
||||
0.0, 360.0,
|
||||
0.0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_ANGLE, pspec);
|
||||
|
||||
/**
|
||||
* ClutterPageTurnEffect:radius:
|
||||
*
|
||||
* The radius of the page curl, in pixels
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
pspec = g_param_spec_float ("radius",
|
||||
"Radius",
|
||||
"The radius of the page curl",
|
||||
-G_MAXFLOAT, G_MAXFLOAT,
|
||||
24.0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_RADIUS, pspec);
|
||||
|
||||
deform_class->deform_vertex = clutter_page_turn_effect_deform_vertex;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_page_turn_effect_init (ClutterPageTurnEffect *self)
|
||||
{
|
||||
self->period = 0.0;
|
||||
self->angle = 0.0;
|
||||
self->radius = 24.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_page_turn_effect_new:
|
||||
* @period: the period of the page curl, between 0.0 and 1.0
|
||||
* @angle: the angle of the page curl, between 0.0 and 360.0
|
||||
* @radius: the radius of the page curl, in pixels
|
||||
*
|
||||
* Creates a new #ClutterPageTurnEffect instance with the given parameters
|
||||
*
|
||||
* Return value: the newly created #ClutterPageTurnEffect
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterEffect *
|
||||
clutter_page_turn_effect_new (gdouble period,
|
||||
gdouble angle,
|
||||
gfloat radius)
|
||||
{
|
||||
g_return_val_if_fail (period >= 0.0 && period <= 1.0, NULL);
|
||||
g_return_val_if_fail (angle >= 0.0 && angle <= 360.0, NULL);
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_PAGE_TURN_EFFECT,
|
||||
"period", period,
|
||||
"angle", angle,
|
||||
"radius", radius,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_page_turn_effect_set_period:
|
||||
* @effect: a #ClutterPageTurnEffect
|
||||
* @period: the period of the page curl, between 0.0 and 1.0
|
||||
*
|
||||
* Sets the period of the page curling, between 0.0 (no curling)
|
||||
* and 1.0 (fully curled)
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_page_turn_effect_set_period (ClutterPageTurnEffect *effect,
|
||||
gdouble period)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect));
|
||||
g_return_if_fail (period >= 0.0 && period <= 1.0);
|
||||
|
||||
effect->period = period;
|
||||
|
||||
clutter_deform_effect_invalidate (CLUTTER_DEFORM_EFFECT (effect));
|
||||
|
||||
g_object_notify (G_OBJECT (effect), "period");
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_page_turn_effect_get_period:
|
||||
* @effect: a #ClutterPageTurnEffect
|
||||
*
|
||||
* Retrieves the value set using clutter_page_turn_effect_get_period()
|
||||
*
|
||||
* Return value: the period of the page curling
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gdouble
|
||||
clutter_page_turn_effect_get_period (ClutterPageTurnEffect *effect)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect), 0.0);
|
||||
|
||||
return effect->period;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_page_turn_effect_set_angle:
|
||||
* @effect: #ClutterPageTurnEffect
|
||||
* @angle: the angle of the page curl, in degrees
|
||||
*
|
||||
* Sets the angle of the page curling, in degrees
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_page_turn_effect_set_angle (ClutterPageTurnEffect *effect,
|
||||
gdouble angle)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect));
|
||||
g_return_if_fail (angle >= 0.0 && angle <= 360.0);
|
||||
|
||||
effect->angle = angle;
|
||||
|
||||
clutter_deform_effect_invalidate (CLUTTER_DEFORM_EFFECT (effect));
|
||||
|
||||
g_object_notify (G_OBJECT (effect), "angle");
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_page_turn_effect_get_angle:
|
||||
* @effect: a #ClutterPageTurnEffect:
|
||||
*
|
||||
* Retrieves the value set using clutter_page_turn_effect_get_angle()
|
||||
*
|
||||
* Return value: the angle of the page curling
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gdouble
|
||||
clutter_page_turn_effect_get_angle (ClutterPageTurnEffect *effect)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect), 0.0);
|
||||
|
||||
return effect->angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_page_turn_effect_set_radius:
|
||||
* @effect: a #ClutterPageTurnEffect:
|
||||
* @radius: the radius of the page curling, in pixels
|
||||
*
|
||||
* Sets the radius of the page curling
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_page_turn_effect_set_radius (ClutterPageTurnEffect *effect,
|
||||
gfloat radius)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect));
|
||||
|
||||
effect->radius = radius;
|
||||
|
||||
clutter_deform_effect_invalidate (CLUTTER_DEFORM_EFFECT (effect));
|
||||
|
||||
g_object_notify (G_OBJECT (effect), "radius");
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_page_turn_effect_get_radius:
|
||||
* @effect: a #ClutterPageTurnEffect
|
||||
*
|
||||
* Retrieves the value set using clutter_page_turn_effect_set_radius()
|
||||
*
|
||||
* Return value: the radius of the page curling
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gfloat
|
||||
clutter_page_turn_effect_get_radius (ClutterPageTurnEffect *effect)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_PAGE_TURN_EFFECT (effect), 0.0);
|
||||
|
||||
return effect->radius;
|
||||
}
|
71
clutter/clutter-page-turn-effect.h
Normal file
71
clutter/clutter-page-turn-effect.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 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/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* Based on MxDeformPageTurn, written by:
|
||||
* Chris Lord <chris@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __CLUTTER_PAGE_TURN_EFFECT_H__
|
||||
#define __CLUTTER_PAGE_TURN_EFFECT_H__
|
||||
|
||||
#include <clutter/clutter-deform-effect.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_PAGE_TURN_EFFECT (clutter_page_turn_effect_get_type ())
|
||||
#define CLUTTER_PAGE_TURN_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_PAGE_TURN_EFFECT, ClutterPageTurnEffect))
|
||||
#define CLUTTER_IS_PAGE_TURN_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_PAGE_TURN_EFFECT))
|
||||
|
||||
/**
|
||||
* ClutterPageTurnEffect:
|
||||
*
|
||||
* <structname>ClutterPageTurnEffect</structname> is an opaque structure
|
||||
* whose members can only be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
typedef struct _ClutterPageTurnEffect ClutterPageTurnEffect;
|
||||
|
||||
GType clutter_page_turn_effect_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterEffect *clutter_page_turn_effect_new (gdouble period,
|
||||
gdouble angle,
|
||||
gfloat radius);
|
||||
|
||||
void clutter_page_turn_effect_set_period (ClutterPageTurnEffect *effect,
|
||||
gdouble period);
|
||||
gdouble clutter_page_turn_effect_get_period (ClutterPageTurnEffect *effect);
|
||||
void clutter_page_turn_effect_set_angle (ClutterPageTurnEffect *effect,
|
||||
gdouble angle);
|
||||
gdouble clutter_page_turn_effect_get_angle (ClutterPageTurnEffect *effect);
|
||||
void clutter_page_turn_effect_set_radius (ClutterPageTurnEffect *effect,
|
||||
gfloat radius);
|
||||
gfloat clutter_page_turn_effect_get_radius (ClutterPageTurnEffect *effect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_PAGE_TURN_EFFECT_H__ */
|
@ -60,6 +60,7 @@
|
||||
#include "clutter-colorize-effect.h"
|
||||
#include "clutter-constraint.h"
|
||||
#include "clutter-container.h"
|
||||
#include "clutter-deform-effect.h"
|
||||
#include "clutter-desaturate-effect.h"
|
||||
#include "clutter-device-manager.h"
|
||||
#include "clutter-drag-action.h"
|
||||
@ -80,6 +81,7 @@
|
||||
#include "clutter-media.h"
|
||||
#include "clutter-model.h"
|
||||
#include "clutter-offscreen-effect.h"
|
||||
#include "clutter-page-turn-effect.h"
|
||||
#include "clutter-path.h"
|
||||
#include "clutter-rectangle.h"
|
||||
#include "clutter-score.h"
|
||||
|
@ -106,6 +106,8 @@
|
||||
<xi:include href="xml/clutter-blur-effect.xml"/>
|
||||
<xi:include href="xml/clutter-colorize-effect.xml"/>
|
||||
<xi:include href="xml/clutter-desaturate-effect.xml"/>
|
||||
<xi:include href="xml/clutter-deform-effect.xml"/>
|
||||
<xi:include href="xml/clutter-page-turn-effect.xml"/>
|
||||
</chapter>
|
||||
|
||||
</part>
|
||||
|
@ -2403,3 +2403,43 @@ CLUTTER_IS_DESATURATE_EFFECT
|
||||
<SUBSECTION Private>
|
||||
clutter_desaturate_effect_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>clutter-deform-effect</FILE>
|
||||
ClutterDeformEffect
|
||||
ClutterDeformEffectClass
|
||||
clutter_deform_effect_set_back_material
|
||||
clutter_deform_effect_get_back_material
|
||||
clutter_deform_effect_set_n_tiles
|
||||
clutter_deform_effect_get_n_tiles
|
||||
<SUBSECTION>
|
||||
clutter_deform_effect_invalidate
|
||||
<SUBSECTION Standard>
|
||||
CLUTTER_TYPE_DEFORM_EFFECT
|
||||
CLUTTER_DEFORM_EFFECT
|
||||
CLUTTER_DEFORM_EFFECT_CLASS
|
||||
CLUTTER_IS_DEFORM_EFFECT
|
||||
CLUTTER_IS_DEFORM_EFFECT_CLASS
|
||||
CLUTTER_DEFORM_EFFECT_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
ClutterDeformEffectPrivate
|
||||
clutter_deform_effect_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>clutter-page-turn-effect</FILE>
|
||||
ClutterPageTurnEffect
|
||||
clutter_page_turn_effect_new
|
||||
clutter_page_turn_effect_set_period
|
||||
clutter_page_turn_effect_get_period
|
||||
clutter_page_turn_effect_set_angle
|
||||
clutter_page_turn_effect_get_angle
|
||||
clutter_page_turn_effect_set_radius
|
||||
clutter_page_turn_effect_get_radius
|
||||
<SUBSECTION Standard>
|
||||
CLUTTER_TYPE_PAGE_TURN_EFFECT
|
||||
CLUTTER_PAGE_TURN_EFFECT
|
||||
CLUTTER_IS_PAGE_TURN_EFFECT
|
||||
<SUBSECTION Private>
|
||||
clutter_page_turn_effect_get_type
|
||||
</SECTION>
|
||||
|
@ -27,6 +27,7 @@ clutter_click_action_get_type
|
||||
clutter_clone_get_type
|
||||
clutter_colorize_effect_get_type
|
||||
clutter_constraint_get_type
|
||||
clutter_deform_effect_get_type
|
||||
clutter_desaturate_effect_get_type
|
||||
clutter_device_manager_get_type
|
||||
clutter_drag_action_get_type
|
||||
@ -43,6 +44,7 @@ clutter_media_get_type
|
||||
clutter_model_get_type
|
||||
clutter_model_iter_get_type
|
||||
clutter_offscreen_effect_get_type
|
||||
clutter_page_turn_effect_get_type
|
||||
clutter_path_get_type
|
||||
clutter_rectangle_get_type
|
||||
clutter_score_get_type
|
||||
|
@ -2,6 +2,28 @@
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
static gboolean
|
||||
on_enter (ClutterActor *actor,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
clutter_actor_animate (actor, CLUTTER_LINEAR, 150,
|
||||
"@effects.curl.period", 0.25,
|
||||
NULL);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_leave (ClutterActor *actor,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
clutter_actor_animate (actor, CLUTTER_LINEAR, 150,
|
||||
"@effects.curl.period", 0.0,
|
||||
NULL);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_drag_begin (ClutterDragAction *action,
|
||||
ClutterActor *actor,
|
||||
@ -156,6 +178,8 @@ test_drag_main (int argc, char *argv[])
|
||||
clutter_actor_set_position (handle, (800 - 128) / 2, (600 - 128) / 2);
|
||||
clutter_actor_set_reactive (handle, TRUE);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), handle);
|
||||
g_signal_connect (handle, "enter-event", G_CALLBACK (on_enter), NULL);
|
||||
g_signal_connect (handle, "leave-event", G_CALLBACK (on_leave), NULL);
|
||||
|
||||
action = clutter_drag_action_new ();
|
||||
clutter_drag_action_set_drag_threshold (CLUTTER_DRAG_ACTION (action),
|
||||
@ -169,6 +193,7 @@ test_drag_main (int argc, char *argv[])
|
||||
clutter_actor_add_action (handle, action);
|
||||
|
||||
clutter_actor_add_effect_with_name (handle, "disable", clutter_desaturate_effect_new (0.0));
|
||||
clutter_actor_add_effect_with_name (handle, "curl", clutter_page_turn_effect_new (0.0, 135.0, 12.0));
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user