<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Chapter 9. Effects</title><link rel="stylesheet" type="text/css" href="style.css"><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot"><link rel="home" href="index.html" title="The Clutter Cookbook"><link rel="up" href="index.html" title="The Clutter Cookbook"><link rel="prev" href="script-state.html" title="4. Connecting ClutterState states in ClutterScript"><link rel="next" href="effects-basic.html" title="2. Changing an actor's paint sequence using ClutterEffect"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 9. Effects</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="script-state.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="effects-basic.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="effects"></a>Chapter 9. Effects</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="effects.html#effects-introduction">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="effects.html#idm140200511423104">1.1. Creating effects using the abstract effect classes</a></span></dt><dt><span class="section"><a href="effects.html#effects-introduction-using-the-built-in-effects">1.2. Using the built-in effects</a></span></dt></dl></dd><dt><span class="section"><a href="effects-basic.html">2. Changing an actor's paint sequence using
<span class="type">ClutterEffect</span></a></span></dt><dd><dl><dt><span class="section"><a href="effects-basic.html#idm140200507882112">2.1. Problem</a></span></dt><dt><span class="section"><a href="effects-basic.html#idm140200506605888">2.2. Solution</a></span></dt><dt><span class="section"><a href="effects-basic.html#idm140200506569200">2.3. Discussion</a></span></dt><dt><span class="section"><a href="effects-basic.html#effects-basic-example">2.4. Full example</a></span></dt></dl></dd><dt><span class="section"><a href="effects-custom-deform.html">3. Creating and animating a custom <span class="type">ClutterDeformEffect</span></a></span></dt><dd><dl><dt><span class="section"><a href="effects-custom-deform.html#idm140200506488720">3.1. Problem</a></span></dt><dt><span class="section"><a href="effects-custom-deform.html#effects-custom-deform-solution">3.2. Solution</a></span></dt><dt><span class="section"><a href="effects-custom-deform.html#effects-custom-deform-discussion">3.3. Discussion</a></span></dt><dt><span class="section"><a href="effects-custom-deform.html#idm140200506403024">3.4. Full example</a></span></dt></dl></dd></dl></div><div class="epigraph"><p>Don't wake me for the end of the world unless it has very
good special effects</p><div class="attribution"><span>—<span class="attribution">Roger Zelazny, from <em class="citetitle">Prince of Chaos</em>
</span></span></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="effects-introduction"></a>1. Introduction</h2></div></div></div><p>Effects modify an actor's appearance, such
as how it is positioned, colored and textured.</p><p>The Clutter API for effects contains several
abstract classes you can subclass to create your own effects.
It also contains several built-in effects you can use to
modify the visual appearance of actors in a variety of ways.</p><p>The recipes in this section of the cookbook cover how to create
your own effects as well as how to apply Clutter's effects.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idm140200511423104"></a>1.1. Creating effects using the abstract effect classes</h3></div></div></div><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3><p>One of the original design goals of Clutter was to abstract
the complexity of GL. However, the effects API partially circumvents
these abstractions, to give you finer-grained access to the
graphics pipeline. Therefore, if you want to write your own effects,
some understanding of Cogl, OpenGL, and general graphics programming
is essential.</p></div><p>Each abstract effect class is tailored to modifying different
aspects of an actor, as explained below:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><b><span class="type">ClutterEffect</span>. </b>If you're just using the Clutter and Cogl APIs to
decorate an actor, this is simplest type of effect to
implement.</p><p>Subclassing <span class="type">ClutterEffect</span> enables you to
"wrap" how an actor is painted, by injecting some code before
and/or after the actor's own <code class="function">paint()</code>
implementation.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>This is the preferred way to modify how an actor is
painted, short of creating your own actor subclass.</p></div><p><span class="emphasis"><em>Subclasses of
<span class="type">ClutterEffect</span></em></span>:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p><b><span class="type">ClutterOffscreenEffect</span>. </b>Use this class as a basis if you need GL textures
for your effect.</p><p>GL textures are required for effects which need
an offscreen framebuffer. The offscreen framebuffer is
used to store a modified rendering of an actor (e.g.
with its colors altered or with deformed geometry).
This buffer is then redirected to a texture in the
stage window.</p><p>An example is <span class="type">ClutterBlurEffect</span>,
which uses a GLSL fragment shader to blur an
actor's appearance in an offscreen framebuffer.</p><p><span class="emphasis"><em>Subclasses of
<span class="type">ClutterOffscreenEffect</span></em></span>:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: square; "><li class="listitem"><p><b><span class="type">ClutterDeformEffect</span>. </b>Use this base class if you want to modify
an actor's geometry, at the level of individual
vertices.</p><p><span class="type">ClutterDeformEffect</span> removes the
complexity of dealing with vertex-based deformations
at the OpenGL level, instead enabling you to easily plug
a deformation callback into the graphics pipeline.</p><p>If you are writing your own deform effects,
a good example to work from is
<span class="type">ClutterPageTurnEffect</span>.</p><p>There is also a
<a class="link" href="effects-custom-deform.html" title="3. Creating and animating a custom ClutterDeformEffect">recipe which
explains how to implement a simple custom deform
effect</a> (a page fold).</p></li><li class="listitem"><p><b><span class="type">ClutterShaderEffect</span>. </b>Use this if you want to apply custom
GLSL vertex or fragment shaders to your actors.</p><p>Writing <span class="type">ClutterShaderEffects</span> gives
you very fine-grained control over the GL pipeline.
However, this makes them the most complex
effects to implement.</p><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3><p>If you want to write your own GLSL shaders, the
<a class="ulink" href="http://www.opengl.org/documentation/glsl/" target="_top">GLSL
specification</a> is a good starting point.</p></div></li></ul></div></li></ul></div></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="effects-introduction-using-the-built-in-effects"></a>1.2. Using the built-in effects</h3></div></div></div><p>Clutter comes with a number of built-in effects
which can easily be applied to your actors. This section
explains how to do this.</p><p>First, create an actor. For this
example, we use a texture loaded with an image:</p><div class="informalexample"><pre class="programlisting">/* filename could be set from command line or constant */
gchar *filename;
/* create a texture */
ClutterActor *texture = clutter_texture_new ();
/* ...set texture size, keep aspect ratio etc... */
/* NB ignoring missing file errors here for brevity */
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
filename,
NULL);
/* ...add texture to the stage... */</pre></div><p>Next, create an instance of an effect; here, we're
creating a <span class="type">ClutterColorizeEffect</span> with a pink tint:</p><div class="informalexample"><pre class="programlisting">ClutterColor *pink = clutter_color_new (230, 187, 210, 255);
ClutterEffect *effect = clutter_colorize_effect_new (pink);</pre></div><p>Finally, apply the effect to the actor:</p><div class="informalexample"><pre class="programlisting">clutter_actor_add_effect (texture, effect);</pre></div><p>The result in this case is an image colorized with
a pink tint, like this:</p><div class="screenshot"><div class="mediaobject"><img src="images/effects-built-in.png" alt="Applying a ClutterColorizeEffect to a texture loaded with an image (drawing by Madeleine Smith)"></div></div><p>The same set of steps applies for any of the built-in
Clutter effects. Your own custom effects classes should also
behave in a similar way: constructors should return
<span class="type">ClutterEffect</span> instances so your effect can
be added to an actor through the standard API.</p><p>One further thing worth mentioning is that because an
effect is a GObject, any properties you expose for your effect
can be animated via implicit animations,
<span class="type">ClutterAnimator</span> or <span class="type">ClutterState</span>. For
example, the <span class="type">ClutterPageTurnEffect</span> can be animated
by manipulating its <code class="varname">period</code> property. An example
of how to do this for your own effect is given in the
<a class="link" href="effects-custom-deform.html" title="3. Creating and animating a custom ClutterDeformEffect">custom deform effect
recipe</a>.</p><p>The full code for the <span class="type">ClutterColorizeEffect</span>
example is below.</p><div class="example"><a name="effects-introduction-example-1"></a><p class="title"><b>Example 9.1. Applying a <span class="type">ClutterColorizeEffect</span> to
a texture loaded with an image</b></p><div class="example-contents"><pre class="programlisting">#include <clutter/clutter.h>
int
main (int argc,
char *argv[])
{
ClutterActor *stage;
ClutterActor *texture;
ClutterConstraint *constraint_x;
ClutterConstraint *constraint_y;
ClutterColor *pink;
ClutterEffect *effect;
gchar *filename;
if (argc < 2)
{
g_print ("Usage: %s <path to image file>\n", argv[0]);
return 1;
}
filename = argv[1];
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_set_size (stage, 400, 400);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
texture = clutter_texture_new ();
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture), TRUE);
clutter_actor_set_width (texture, 300);
/* NB ignoring missing file errors here for brevity */
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
filename,
NULL);
/* align the texture on the x and y axes */
constraint_x = clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5);
constraint_y = clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5);
clutter_actor_add_constraint (texture, constraint_x);
clutter_actor_add_constraint (texture, constraint_y);
/* create a colorize effect with pink tint */
pink = clutter_color_new (230, 187, 210, 255);
effect = clutter_colorize_effect_new (pink);
/* apply the effect to the texture */
clutter_actor_add_effect (texture, effect);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), texture);
clutter_actor_show (stage);
clutter_main ();
return 0;
}
</pre></div></div><br class="example-break"></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="script-state.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="effects-basic.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4. Connecting <span class="type">ClutterState</span> states in <span class="type">ClutterScript</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 2. Changing an actor's paint sequence using
<span class="type">ClutterEffect</span></td></tr></table></div></body></html>