Tuesday, 10 May 2011

A simple transition effect with Clutter

When doing something with graphics, your first need an idea (granted, as with pretty much everything else). In this case, a simple transition that I've seen somewhere a long time ago and I wanted to reproduce with Clutter.

The code is available in a branch of a media explorer I'm currently working on. A few bullet points to follow the code:
  • As the effect needs a "screenshot" of a Clutter scene to play with. You first need to create a subclass of ClutterOffscreenEffect as it does the work of redirecting the painting of a subtree of actors in an offscreen buffer that you can  reuse to texture the rectangles you'll be animating in the effect. This subclass has a "progress" property to control the animation.
  • Then actually compute the coordinates of the grid cells both in screen space and in texture space. To be able to use cogl_rectangles_with_texture_coords(), to try limit the number of GL calls (and/or by the Cogl journal and to ease the animation of the cells fading out, I decided to store the diagonals of the rectangle in a 1D array so that the following grid:

    is stored as the following array:
  • ::paint_target()looks at the "progress" property, animate those grid cells accordingly and draw them. priv->rects is the array storing the initial rectangles, priv->animated_rects the animated ones and priv->chunks stores the start and duration of each diagonal animation along with a (index, length) tuple that references the diagonal rectangles in priv->rects and priv->animated_rects.
Some more details:
  • in the ::paint_target() function, you can special case when the progress is 0.0 (paint the whole FBO instead of the textured grid) and 1.0 (don't do anything),
  • Clutter does not currently allow to just rerun the effect when you animate a property of an offscreen effect for instance. This means that when animating the "progress" property on the effect, it queues a redraw on the actor that end up in the offscreen to trigger the effect ::paint_target() again. A branch from Neil allows to queue a "rerun" on the effect to avoid having to do that,
  • The code has some limitations right now (ie, n_colums must be equal to n_rows) but easily fixable. Once done, it makes sense to try to push the effect to Mx.

1 comment:

  1. This is very cool! Now you just need to make it rotate the tiles and flip between two actors like in Portal 2: http://www.youtube.com/watch?v=ZPthzbly8FQ :) It looks like that alternates between different directions as well. Maybe a property to say which direction the tiles should head it would be good? If only Clutter had a sound library for the clacking effect..