[reactive] crayon - a 2D opengl curve renderer,
with Reactive animations
Jules Bean
jules at jellybean.co.uk
Wed Mar 25 14:59:38 EDT 2009
Hi,
I have just uploaded another little proof-of-concept reactive toy.
http://roobarb.jellybean.co.uk/~jules/crayon.8.tgz
The important part is the beginnings of an OpenGL accelerated 2D
rendering engine, for rendering parametric curves and in particular
bezier curves. The way it works at the moment is:
* A sampling step tries to adaptively generate points on the curve to
approximate it as a polygon. This is done on the CPU, isn't as
clever as it could be, but turns out to be not the bottleneck right
now
* For stroked regions, this is 'thickened' out to a stroke using
difference-based approximations to a tangent. This works well for
smooth curves but poorly at end points and sharp corners. For filled
regions the GLU tessellator is used to convert it to GL primitives,
normally triangles.
* Then this is rendered by openGL in either immediate mode or using
VAs.
Currently the sampling and GLU tessellation can be cached and not
redone every frame, if the appropriate part of the structure doesn't
change each frame. You need to use standard GHC sharing to make this
work - define constant picture fragments at a high enough scope that
they get shared. The stroke generation is not cached and this turns out
to be pretty expensive. You may need to compile with -fno-state-hack
to get proper sharing (GHC "issue"/bug).
I discovered a bug in the HOpenGL GLU binding. I don't think this demo
tickles the bug so it should run on a standard build, details of that
bug on the hopengl list.
The immediate mode renderer turns out to be faster than the VA based
renderer, at least for these small demos. I think that's because the
extra pass over the data structure (to generate the VAs) is a
relatively high cost, the number of vertices is small, and I'm not
smart about sharing vertices.
I then plugged all this into Reactive and set up three simple
animations - some spinning flowers, some business-like charts, and a
classic pong game. You can switch between them using your left + right
arrows keys, and they spin in + out using a simple animation, whilst
their own animations continue independently. Exactly the kind of thing
Reactive is supposed to make easy!
The framerate is artificially limited to save battery life when
developing.
As before, this code uses my incomplete Reactive implementation not
Conal's; it should be easy to port although I think some of my
primitives have slightly different names.
I'm not going to work on this code for a bit, but I have in mind
various possible extensions, including using the GPU to do some of the
heavy lifting, using a fragment shader to support gradients and other
kinds of procedural texturing, supporting implicit curves as well as
parametric ones. I'm interested in any thoughts on how to design a
useful attractive combinator library for 2D graphics.
The real target is to have something fast enough to make an expressive
library for complex smooth animations, e.g. 2D games.
Jules
More information about the Reactive
mailing list