ffmpeg for rendering the animation to video files.
To understand the code you need to have some background knowledge of the OpenGL rendering pipeline and the OpenGL shading language. Beginners may start by learning how to draw a triangle on the screen with shader programs and then move on to more advanced topics like framebuffers and projective transformations.
You may simply run
and use keyboard and mouse to play with the simulation (for keyboard and mouse control please see the printed doc).
Here -size is the size of the window, -fps is the frames per second of the animation, if not specified then max possible value will be used, -conf is the line number of the pattern that the program will load from the file config.txt (which contains a few precomputed patterns), -scale is the "resolution" of the texture.
You may also use an image file to control the growth of the pattern by adding the -mask option:
How to render the animation to a video file
Firstly make sure ffmpeg is installed on your computer and can be found on system path, windows users need to manually set the variable FFMPEG_EXE to be the path to your ffmpeg.exe, then press Ctrl+v to start rendering the animation to a .mp4 video and press Ctrl+v again to stop the rendering.
You can use the option -videorate to control the frames per second of the video (not the animation!) and the option -samplerate to control how often a frame is sampled from the animation. If the frames are sampled too frequently then the size of the video file will grow very large.
About the code
pyglet is only a thin wrapper of OpenGL so one has to write his own classes to manage things like vao, vbo, framebuffer, etc. There are some modules like vispy and gletools that do this job, but that lays the burden of learning one more package.
I wrote two scripts shader.py and framebuffer.py for compiling the shader programs and rendering to texture. They are not meant to be serious tools, just kept simple and suffice for our work.
The GLSL code borrows heavily from pmneila's work, the most genius part in his code is the use of a brush variable (u_mouse in our program) as the interface between the shader and the UI.