ClutterEffect

ClutterEffect — Base class for actor effects

Synopsis

                    ClutterEffect;
                    ClutterEffectClass;

Object Hierarchy

  GObject
   +----GInitiallyUnowned
         +----ClutterActorMeta
               +----ClutterEffect
                     +----ClutterOffscreenEffect

Description

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.

Implementing a ClutterEffect

Creating a sub-class of ClutterEffect requires the implementation of three virtual functions:

The prepare() 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.

The pre_paint() function should be used to set up the ClutterEffect right before the ClutterActor's paint sequence. This function, like prepare() can fail, and return FALSE; in that case, no post_paint() invocation will follow.

The post_paint() function is called after the ClutterActor's paint sequence.

The pre_paint() phase could be seen as a custom handler to the "paint" signal, while the post_paint() phase could be seen as a custom handler to the "paint" signal connected using 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 prepare() phase will create the two materials used for the two different rectangles; the pre_paint() function will paint the first material using cogl_rectangle(), while the post_paint() phase will paint the second material.

 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

Details

ClutterEffect

typedef struct _ClutterEffect ClutterEffect;

The ClutterEffect structure contains only private data and should be accessed using the provided API

Since 1.4


ClutterEffectClass

typedef struct {
  gboolean (* pre_paint)  (ClutterEffect *effect);
  void     (* post_paint) (ClutterEffect *effect);
} ClutterEffectClass;

The ClutterEffectClass structure contains only private data

pre_paint ()

virtual function

post_paint ()

virtual function

Since 1.4