On 9/13/2010 6:55 AM, Jonathan Hartley wrote:
On Sep 10, 7:48 pm, Ken Seehart<[email protected]>  wrote:
After hacking around a bit, I came up with this attempt:

   buffer = fleet[0]._vertex_list.domain.attribute_names['vertices'].buffer
   vertices = ctypes.cast(buffer.data_ptr, POINTER(ctypes.c_int))

And sure enough, vertices contains the points. However, writing to them
turns out to be "pointless" because batch.draw recalculates them. And
in any case it's rather abusive code relying on hidden implementation.

However, this points me in the right direction. Really I should just
forget about using high level Sprite objects and just use textures
directly instead. My computational shared library can process the
vertex array. It will be quite instantaneous since it is CUDA.

On 09/09/2010 06:37 PM, KenSeehart wrote:

I know how to use arrays to control batches of points and lines and
stuff. But how do I control a batch of sprites with an array?
The telemetry of the sprites will be updated in a high speed shared
library via ctypes, which will write to an array of x,y coordinates,
compatible with a pyglet.graphics.vertex_list.
My specific goal is to avoid O(n) iteration of python code for about
2000 sprites, so writing a python loop to copy the position data into
the sprite objects is not fast enough, and shouldn't be necessary.
In other words, I'd like to bind a vertex_list (or any kind of flat
array) to a batch of sprites.
Thanks,
Ken
Hey Ken, this sounds really exciting, I for one would be really happy
to hear you report back when you've made any more progress, especially
if you can link to your code.

Cheers,

   Jonathan
Got it working. I just roll my own sprites rather than using the Sprite class. Hopefully next month when I am less busy I can put together a demo and/or propose a patch. If anyone is working on this kind of thing in the pyglet code base, let me know.

   # untested semi-pseudocode follows...

   from ctypes import *
   aeropath = cdll.aeropath
   # ... some ctypes wrapper code for aeropath...

   class Point2D(Structure):
        _fields_ = [('x', c_double),
                    ('y', c_double),
                    ]

        def __repr__(self):
            return '(%0.2f, %0.2f)' % (self.x, self.y)

   nfleet = 4096
   im_fleet = pyglet.image.load('images/aircraft.png')
   fleet_texture = im_fleet.get_texture()
   fleet_batch = pyglet.graphics.Batch()

   vertex_list = fleet_batch.add(4*nfleet, GL_QUADS,
   TextureBindGroup(fleet_texture),
                                  'v2d',
                                  ('t2f', (0.0, 0.0, 1.0, 0.0, 1.0,
   1.0, 0.0, 1.0)*nfleet))

   quads = cast(addressof(vertex_list.vertices), POINTER(Point2D))

   # I pass quads to my CUDA library which calculates trajectories for
   all the sprites and then calculates the quads from the trajectories.
   aeropath.get_trajectories_and_quads(nfleet, quads, ... )
   vertex_list.vertices # this attribute access magically triggers an
   update (host to device copy)


I'm getting 60 FPS with thousands of sprites this way. It would be kind of nice to get this integrated into the pyglet Sprite class.

I have another question:

Is there a way to get at the device buffer that is internally mapped to the quad array? Currently, my code has the effect of copying from the device to the host and back again, which should be unnecessary. If I had the device buffer pointer, I could pass that directly to my CUDA code.

I feel that even high level python wrappers should generally provide easy access to low level functionality. I want to be able to either throw together a pyglet app in pure python or interoperate with my own C and CUDA libraries, or any combination.

I don't think we should have to choose between high level and low level tools. Pyglet generally does a great job in this respect (providing a combination of a lightweight wrapper with high-level functionality), so lets keep making it even better. Sometimes this philosophy comes into conflict with OO ideas such as "implementation hiding". But I think it is important not to automatically do implementation hiding without also thinking about the possible benefits of exposing low level access where appropriate, especially where what is subject to hiding is not likely to be subject to future change. The trouble with high-level code is that it involves guessing the needs of the user, whereas exposing low level access does not.

Ken

--
You received this message because you are subscribed to the Google Groups 
"pyglet-users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/pyglet-users?hl=en.

Reply via email to