I know nothing of toonloop, so I'm guessing here, but I think your problem
is not what you think it is, and from your problem description, it's likely
you are not using openGL in the way it is meant to be used.

pygame.image.tostring is plenty fast, as fast as a pygame blit it's
extremely unlikely it represents any kind of bottleneck whatsoever. If you
want to test this yourself, temporarily hack your app to just keep sending
the same string up to the card over and over again (i.e. eliminate the
tostring call), and check your frame rate. I expect you'll see no difference
at all.

Your slowness is probably caused by either uploading textures to opengl
being a relatively slow operation (this is true no matter how you got the
bytes to send to it) and/or your program being blocked by the OpenGL queue
processing when you try to change a texture which there are pending
operations on. (you aren't reusing the same single texture over and over
again, are you?)

The speed of hardware acceleration really comes from 2 specific things -
first is that you do complex operations on a set of textures which have
already been uploaded to the card (meaning you make a lot of pixels draw
with a relatively small set of vertex data being sent each frame), second is
that you are taking advantage of parallelism by making the graphics card do
work independently of your CPU (meaning you send commands that the graphics
card can do on it's own time and won't block the rest of what your program
does).

If you upload a new image every frame, you are not able to take advantage of
the first way in which hardware acceleration speeds things up (you are
basically sending all the pixels over to the card). If you are changing the
content of textures as the graphics card is trying to draw them, you are not
able to take advantage of the second way (the cpu ends up having to wait on
the card being done with the texture before it can change it)

you are probably right to think the whole thing should be done in pygame,
but there are probably ways you could speed stuff up if there is a good
reason to stick with opengl.

The best way to do this in opengl, would be to load all the distinct frames
into textures ahead of time, and then draw through them.

Barring that, you could probably make the routine at least twice as fast by
rotating through a pool of textures (so that you are never waiting to change
a texture as it's being drawn)

Also, you should probably use RGB instead of RGBX (should take 3/4ths the
bandwidth to the card), there's no point in sending a dummy byte to the
graphics card, when it comes to uploading textures, total bytes sent is
generally much much more important than alignment issues.


On Sun, Jan 3, 2010 at 8:06 PM, Alexandre Quessy <[email protected]>wrote:

> Hello Pygame users and developers !
>
> Is there a way I can speed up the transfert from a surface to an
> OpenGL texture ? Right now, I use the pygame.image.tostring function,
> but it seems like converting the pixels to a Python str creates a
> serious bottle neck in my stop motion application...
>
> I think that it should either be implemented directly in Pygame, (best
> option) or done using something like ctypes in my application. If none
> of these option is not easy enough, I am thinking about switching to
> Gstreamer+GTK with the GdkPixBuf, instead of Pygame surfaces. An other
> option would be to rewrite the whole application in C++...
>
> Any suggestion to fix this in a way that is not too long ?
> My frame rate drops to 4 FPS when there are more than a few surfaces in my
> list.
> Please try Toonloop to test this out. It works well on Linux. If
> someone get it to work on Mac or Windows, I would need hints for
> packaging it for those OS too. I convert the surfaces to OpenGL
> texture in texture_from_image from the file
> http://bitbucket.org/aalex/toonloop1/src/tip/toon/draw.py on what is
> currently the line 42.
> --
> Alexandre Quessy
> http://alexandre.quessy.net/
>

Reply via email to