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.
- As the effect needs a “screenshot” of a Clutter scene to play with. You first need to create a subclass of
ClutterOffscreenEffectas 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:
::paint_target()looks at the “progress” property, animate those grid cells accordingly and draw them.
priv->rectsis the array storing the initial rectangles,
priv->animated_rectsthe animated ones and
priv->chunksstores 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.