![]() |
![]() |
![]() |
Clutter Reference Manual | ![]() |
---|---|---|---|---|
Top | Description | Object Hierarchy |
GObject +----GInitiallyUnowned +----ClutterActorMeta +----ClutterEffect +----ClutterOffscreenEffect
The ClutterEffect class provides a default type and API for creating effects for generic actors.
Effects are a ClutterActorMeta sub-class that modify the way an actor is painted in a way that is not part of the actor's implementation.
Effects should be the preferred way to affect the paint sequence of an actor without sub-classing the actor itself and overriding the "paint" virtual function.
Creating a sub-class of ClutterEffect requires the implementation of three virtual functions:
prepare()
, which is called when
attaching the ClutterEffect to a ClutterActor through the
clutter_actor_add_effect()
function or when the actor is being
painted;pre_paint()
, which is called
before painting the ClutterActor.post_paint()
, which is called
after painting the ClutterActor.The
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.prepare()
The
function should be used to set
up the ClutterEffect right before the ClutterActor's paint
sequence. This function, like pre_paint()
can fail, and
return prepare()
FALSE
; in that case, no
invocation will follow.post_paint()
The
function is called after the
ClutterActor's paint sequence.post_paint()
The
phase could be seen as a custom
handler to the "paint" signal, while the
pre_paint()
phase could be seen as a custom handler
to the "paint" signal connected using
post_paint()
g_signal_connect_after()
.
Example 3. A simple ClutterEffect implementation
The example below creates two rectangles: one will be painted
"behind" the actor, while another will be painted "on top" of the actor.
The
phase will create the two materials
used for the two different rectangles; the
prepare()
function will paint the first material
using pre_paint()
cogl_rectangle()
, while the
phase will paint the second material.post_paint()
typedef struct { ClutterEffect parent_instance; CoglHandle rect_1; CoglHandle rect_2; } MyEffect; typedef struct _ClutterEffectClass MyEffectClass; G_DEFINE_TYPE (MyEffect, my_effect, CLUTTER_TYPE_EFFECT); static void my_effect_set_actor (ClutterActorMeta *meta, ClutterActor *actor) { MyEffect *self = MY_EFFECT (meta); /* Clear the previous state */ if (self->rect_1) { cogl_handle_unref (self->rect_1); self->rect_1 = NULL; } if (self->rect_2) { cogl_handle_unref (self->rect_2); self->rect_2 = NULL; } /* Maintain a pointer to the actor * self->actor = actor; /* If we've been detached by the actor then we should * just bail out here */ if (self->actor == NULL) return; /* Create a red material */ self->rect_1 = cogl_material_new (); cogl_material_set_color4f (self->rect_1, 1.0, 0.0, 0.0, 1.0); /* Create a green material */ self->rect_2 = cogl_material_new (); cogl_material_set_color4f (self->rect_2, 0.0, 1.0, 0.0, 1.0); } static gboolean my_effect_pre_paint (ClutterEffect *effect) { MyEffect *self = MY_EFFECT (effect); gfloat width, height; /* If we were disabled we don't need to paint anything */ if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) return FALSE; clutter_actor_get_size (self->actor, &width, &height); /* Paint the first rectangle in the upper left quadrant */ cogl_set_source (self->rect_1); cogl_rectangle (0, 0, width / 2, height / 2); return TRUE; } static void my_effect_post_paint (ClutterEffect *effect) { MyEffect *self = MY_EFFECT (effect); gfloat width, height; clutter_actor_get_size (self->actor, &width, &height); /* Paint the second rectangle in the lower right quadrant */ cogl_set_source (self->rect_2); cogl_rectangle (width / 2, height / 2, width, height); } static void my_effect_class_init (MyEffectClass *klass) { ClutterActorMetaClas *meta_class = CLUTTER_ACTOR_META_CLASS (klass); meta_class->set_actor = my_effect_set_actor; klass->pre_paint = my_effect_pre_paint; klass->post_paint = my_effect_post_paint; }
ClutterEffect is available since Clutter 1.4
typedef struct _ClutterEffect ClutterEffect;
The ClutterEffect structure contains only private data and should be accessed using the provided API
Since 1.4
typedef struct { gboolean (* pre_paint) (ClutterEffect *effect); void (* post_paint) (ClutterEffect *effect); } ClutterEffectClass;
The ClutterEffectClass structure contains only private data
Since 1.4