Live coding of graphics

From Toplap
Revision as of 07:41, 24 July 2010 by 213.5.64.19 (talk) (→‎Logo)
Jump to navigation Jump to search

First some history.

1342,  :O,  bfvyfk,  witqy,  860,  :-PP,  tlajo,  607447,

Scheme

I mentioned earlier on that Logo was a variant of Lisp, well another (closer one) is Scheme. Here is the spiral program rewritten in scheme:

(define (spiral distance)
    (forward distance) (right 15)
    (if (> distance 30)
        1
        (spiral (* distance 1.02))))

Scheme is a tiny, simple language. Like logo, scheme is often used as a teaching tool, for it's elegance and simplicity. People often use it to learn about programming languages, and as an extension scripting language for applications like the gimp. I wouldn't really like to write huge applications natively in scheme, but it has its merits as a live programming language, as you can get a lot done per line of code.

The prefix style--doing arithmetic like (* 4 5) where the operator goes first--seems confusing to begin with, but it actually makes the language a lot simpler as all function calls are the same. It's really easy to do recursion (actually, it's the only way of looping in Scheme), and also you can easily write scheme programs that edit and parse other scheme programs, but I haven't investigated this too much yet.

My first livecoding graphics environment was just a hacked version of a scheme example which implemented turtle graphics in a window. I changed the program to execute its scheme script every frame in a loop, so you could change stuff live.

Fluxus

Fluxus is a 3D rendering environment, a smaller version of the renderers you get in a game engine such as Unreal or Quake. It's also got a few extra features that game engines do not usually have, firstly it can capture audio input, and process the audio to extract the harmonic content of the sound. Secondly it is entirely driven by a realtime scheme script editor - for live coding.

As fluxus produces 3D objects, rather than lines - the graphics code is a little more complicated than the turtle graphics we've already seen. Fluxus uses a common method used in graphics, based on the OpenGL library that it uses, the state machine.

Lets have a look at some fluxus code:

(colour (vector 1 0 0))
(draw-cube)
(colour (vector 0 1 0))
(draw-cube)

This fragment of script will draw a red cube and then a green cube. As the state of the colour state is changed, it effects the commands passed after it.

These states can also be stacked, using push and pop commands - which means to take a copy of the current state so you can change it and then pop it back to how it was before:

(colour (vector 1 0 0))
(push)
(colour (vector 0 1 0))
(draw-cube)
(pop)
(draw-cube)

This will set the colour to red, then push the state, and draw a green cube. The pop then sets the state back to how it was before the push, and will then draw a red cube. I sometimes indent pushed state code like that to make it easier to read.

There are a few items that you can modify on the fluxus state machine - one of the most important is the transform state. This allows you to translate, rotate and scale objects, and follows the same rules as the colour state. As with Logo (where the state was just as important, but was implicit in the postion and orientation of the turtle) manipulating the state is handy for recursive modelling.

(define (tree d)
 (push)
 (rotate (vector 0 30 0))     ; twist the branch
 (translate (vector 0 0.4 0)) ; move up a bit
 (scale (vector 0.8 0.8 0.8)) ; shrink so branches get smaller
 (push)
 (scale (vector 0.1 0.6 0.1)) ; make the cube thinner and more branch like
 (draw-cube) ; this is our cube 
 (pop)
 (cond
    ((not (zero? d))
     (rotate (vector 0 0 45))
     (tree (- d 1))             ; one subtree branch
     (rotate (vector 0 0 -90))
     (tree (- d 1))))            ; another subtree branch
 (pop))
(colour (vector 1 1 1)) ; set current colour to white
(every-frame (tree 10)) ; draw the tree every frame

http://www.pawfal.org/nebogeo/images/tree2.png

Another tree.

Live programming with fluxus

The audio input features combined with the same recursive graphics that come all the way from the days of Logo allow the live programmer to quickly make complex shapes that dance to sound (of course it works better if that sound is live coded too). I've found the best way to "play" fluxus in this way is to rig up a template recursive function that you can work on throughout a performance - adding new modifications and recursion depths as you see fit.

There is more to fluxus than recursion though. There are features allowing you to employ physics animation to your scene, so objects can fall, bounce off each other or be kicked around to the music. Also there is a full flocking system for boid like behaviours. One of the newest additions is a turtle style polygon modeller, so you can use a turtle to draw polygons and join them together into 3D shapes.

Links:

The logo figures in this document were produced with the Berkeley Logo distribution which can be downloaded from here: http://www.cs.berkeley.edu/~bh/logo.html