![]() |
![]() |
![]() |
Clutter Reference Manual | ![]() |
---|---|---|---|---|
Top | Description | Object Hierarchy |
ClutterEffect;
struct ClutterEffectClass;
void clutter_effect_queue_rerun (ClutterEffect *effect
);
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 overriding the ‘paint’ method. The implementation of the function should look something like this:
void effect_paint (ClutterEffect *effect, ClutterEffectPaintFlags flags) { /* Set up initialisation of the paint such as binding a CoglOffscreen or other operations */ /* Chain to the next item in the paint sequence. This will either call ‘paint’ on the next effect or just paint the actor if this is the last effect. */ ClutterActor *actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); clutter_actor_continue_paint (actor); /* perform any cleanup of state, such as popping the CoglOffscreen */ }
The effect can optionally avoid calling
clutter_actor_continue_paint()
to skip any further stages of
the paint sequence. This is useful for example if the effect
contains a cached image of the actor. In that case it can
optimise painting by avoiding the actor paint and instead
painting the cached image. The CLUTTER_EFFECT_RUN_ACTOR_DIRTY
flag is useful in this case. Clutter will set this flag when a
redraw has been queued on the actor since it was last
painted. The effect can use this information to decide if the
cached image is still valid.
The ‘paint’ virtual was added in Clutter 1.8. Prior to that there were two separate functions as follows.
pre_paint()
, which is called
before painting the ClutterActor.post_paint()
, which is called
after painting the ClutterActor.The
function was used to set
up the ClutterEffect right before the ClutterActor's paint
sequence. This function can fail, and return pre_paint()
FALSE
; in that case, no
invocation will follow.post_paint()
The
function was called after the
ClutterActor's paint sequence.post_paint()
With these two functions it is not possible to skip the rest of
the paint sequence. The default implementation of the ‘paint’
virtual calls pre_paint()
, clutter_actor_continue_paint()
and
then post_paint()
so that existing actors that aren't using the
paint virtual will continue to work. New actors using the paint
virtual do not need to implement pre or post paint.
Example 4. 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
implementation will create the two materials used for the two
different rectangles; the set_actor()
function
will paint the first material using paint()
cogl_rectangle()
, before
continuing and then it will paint paint the second material
after.
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_paint (ClutterEffect *effect) { MyEffect *self = MY_EFFECT (effect); gfloat width, height; 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); /* Continue to the rest of the paint sequence */ clutter_actor_continue_paint (self->actor); /* 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->paint = my_effect_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
struct ClutterEffectClass { gboolean (* pre_paint) (ClutterEffect *effect); void (* post_paint) (ClutterEffect *effect); gboolean (* get_paint_volume) (ClutterEffect *effect, ClutterPaintVolume *volume); void (* paint) (ClutterEffect *effect, ClutterEffectPaintFlags flags); void (* pick) (ClutterEffect *effect, ClutterEffectPaintFlags flags); };
The ClutterEffectClass structure contains only private data
virtual function | |
virtual function | |
virtual function | |
virtual function | |
Since 1.4