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.