Thursday, January 8

Multi-texture support for pyglet vertex lists

I wrote this little hack to allow easy expression of multiple sets of texture coordinates in pyglet vertex lists. I wrote it so I could use the texture splatting technique to draw a terrain map for a game. For that purpose it works very well. It does a small bit of monkey-patching to pyglet itself, so it may break if things are refactored, but it works good for 1.1.x.

To use it, you instantiate your vertex list the normal way except you can specify multiple sets of texture coordinates. Then you call multitexture.enable() passing it your new vertex list. Here's a simple example:

vl = pyglet.graphics.vertex_list(4,
('v2f', (100, 100, 200, 100, 200, 200, 100, 200)),
('t2f', (0, 0, 1, 0, 1, 1, 0, 1)),
('t2f', (0, 0, 0.25, 0, 0.25, 0.25, 0, 0.25)),
)
multitexture.enable(vl)

You can get the module here.

Labels:

Tuesday, August 19

Cloudy with a Chance of...

I got inspired to add another example to my Python noise library. This one creates a real-time animated atmosphere around planet Earth. It uses the GLSL fast fake noise implementation in the library.


(download a higher quality video)

The example uses pyglet. I cooked up a nice little class for capturing frames to png files that can be encoded into a video. It was used to make the above:
class MovieCapture:

def __init__(self, dirname):
assert os.path.isdir(dirname), (
"%s is not a valid directory" % dirname)
self.dirname = dirname
self.frame_no = 0

def capture(self):
"""Capture the current window a file,
return the file name"""
filename = 'frame-%05d.png'
while os.path.exists(os.path.join(
self.dirname, filename % self.frame_no)):
self.frame_no += 1
mgr = pyglet.image.get_buffer_manager()
mgr.get_color_buffer().save(
os.path.join(self.dirname,
filename % self.frame_no))
return filename % self.frame_no

When you instantiate it, you provide a path to a directory to write the captured frames into. Each is written to a sequentially named png file. After drawing each frame, you simply call the capture() method to write it to a new file. Once you've got the frames you need, you can encode them into a movie using mencoder or whatever tool you choose. To make this video I used mencoder like so:

mencoder "mf://atmosphere/*.png" -mf fps=20 -o atmosphere.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=800

Labels: , , , ,