There's some useful tips here -- thanks. Just some notes...
> #Convert Unicode strings to integers. Provided by Alex Holkner on the
> mailing list.
> components = map(ord, list(data))
Actually this converts 8-bit strings to integers. If you ever find
the need to map Unicode strings, use uniord instead of ord.
> #components only contains one pixel. I want to return a color that I
> can pass to
> #pyglet.gl.glColor4f(), so I need to put it in the 0.0-1.0 range.
> return [float(c) / 255.0 for c in components]
All of pyglet's new graphics and text features use colors in the range
0-255 now, so this conversion hopefully won't be necessary too often.
> I should also mention that writing a paint program in a double-
> buffered environment can be interesting. I was frustrated for a few
> hours before I came up with easy ways to draw everything twice.
I think the majority of your issues (both in ease of implementation
and performance) are due to you using the framebuffer(s) as the main
source of image data. There might be good reasons for this that I'm
unaware of, but for an "ordinary" paint program such as Photoshop or
The Gimp, it will be much easier to keep your image data in an
offscreen buffer of your choosing.
For example, you could use an array of ints, an a ctypes array of
structs, a Numpy array, ... all types that are easier to manipulate
than strings. It's much faster to convert any of these types into
texture data (e.g., using blit_into) than vice-versa. This is due not
only to the limited bandwidth in pulling image data off the video
card, but also because pyglet isn't optimised to produce image data in
any type except strings (whereas it will accept image data in several
other formats). You also won't have to worry about the
double-buffered issue.
Having said that, congratulations on getting such a difficult program working!
Alex.