Optimization advice for Sprites

72 views
Skip to first unread message

Aaron

unread,
Feb 7, 2011, 6:54:56 PM2/7/11
to pyglet-users
I've having speed trouble in rendering Sprites.

I've been able to put everything inside a single Batch, but if I add
too many animated Sprites my game starts slowing down. I think I've
found a limit of about 75 animated Sprites at once on the screen,
which for various reasons I need to go over.

Any suggestions for optimizations I can do short of working with raw
OpenGL or pushing it off to a C package?

Richard Jones

unread,
Feb 7, 2011, 7:20:09 PM2/7/11
to pyglet...@googlegroups.com
On Tue, Feb 8, 2011 at 10:54 AM, Aaron <vide...@gmail.com> wrote:
> I've having speed trouble in rendering Sprites.
>
> I've been able to put everything inside a single Batch, but if I add
> too many animated Sprites my game starts slowing down. I think I've
> found a limit of about 75 animated Sprites at once on the screen,
> which for various reasons I need to go over.

Are all the sprites being updated every frame? Even if they are 75 is
very low. What hardware are you running on? What GL driver are you
using? Even Mesa shouldn't suck that much (in fact for 2d sprites Mesa
is quite well-optimised).

If you have the pyglet source, please try running
contrib/spryte/los.py and tell me what FPS you get for 100 sprites. On
my MacBook I get:

$ python los.py 100
best FPS: 447.955997975
best us per sprite: 22.3236211709
avg us per sprite: 25.2170330363
$ python los.py 1000
best FPS: 50.1406737446
best us per sprite: 19.9438883708
avg us per sprite: 21.4141262726


> Any suggestions for optimizations I can do short of working with raw
> OpenGL or pushing it off to a C package?

You might consider using rabbyt rather than implementing your own.


Richard

Aaron

unread,
Feb 7, 2011, 8:28:26 PM2/7/11
to pyglet-users
This is on a Macintosh with Mac OS X 10.6.6.

There are ~75 animated, as well as many more static sprites. If by
update you mean coordinates and rotation, then no I am not updating
any sprites each frame.

I'd post a link to a picture of my game so that you know what I'm
talking about, but Google Groups won't allow that.

As for that test you suggested, I didn't have the Pyglet source on me
so I downloaded it. I honestly could not find any contrib folder.

Richard Jones

unread,
Feb 7, 2011, 8:30:28 PM2/7/11
to pyglet...@googlegroups.com
On Tue, Feb 8, 2011 at 12:28 PM, Aaron <vide...@gmail.com> wrote:
> As for that test you suggested, I didn't have the Pyglet source on me
> so I downloaded it. I honestly could not find any contrib folder.

Sorry, it's only present if you check the source out from the
repository - I'd forgotten that.


Richard

Aaron

unread,
Feb 7, 2011, 9:30:24 PM2/7/11
to pyglet-users
In any case, I just tried the los.py program.

$ python los.py 100
best FPS: 514.567314839
best us per sprite: 19.4338033366
avg us per sprite: 21.6097511322

$ python los.py 1000
best FPS: 66.0796080254
best us per sprite: 15.1332616806
avg us per sprite: 16.897357462

I suppose I can explain how I'm creating my animations. Most
animations come from a sprite sheet file that I convert into an
ImageGrid.

image = pyglet.resource.image(imagePath)

# Right now, all sprites are supposed to fit in a 32x32 square
width = image.width // constants.TILE_SIZE
height = image.height // constants.TILE_SIZE

imageGrid = pyglet.image.TextureGrid(pyglet.image.ImageGrid(image,
height, width) )

animation = imageGrid.get_animation(period)

Sometimes I have multiple animations inside a single sprite sheet, one
animation per row. It is these types of animations that seem to cause
slowdown when used in large quantities. When I have about 100 of these
kinds of Sprites (on top of any animated Sprites I already have) I get
noticeable slowdown.

image = pyglet.resource.image(imagePath)

width = image.width // const.TILE_HALF_SIZE
height = image.height // const.TILE_HALF_SIZE

imageGrid =
pyglet.image.TextureGrid( pyglet.image.ImageGrid(image, height,
width) )

animationSet = [
pyglet.image.Animation.from_image_sequence(
[imageGrid[(y, x)] for x in xrange(width)],
period
)
for y in xrange(height)
]

# Not actually how I use animationSet.
sprite0 = pyglet.sprite.Sprite(animationSet[0], x = x, y = y,
batch = batch, group = group)
sprite1 = pyglet.sprite.Sprite(animationSet[1], x = x, y = y,
batch = batch, group = group)

Phillip Nguyen

unread,
Feb 7, 2011, 11:35:30 PM2/7/11
to pyglet-users

I also had problems with animated sprites being too slow in my own
project, where I was drawing hundreds of different animated sprites to
the screen at once. It's been a while so I don't remember all of the
details, but I think that I decided the slow-down was the fault of
using clock.schedule_once() in the _animate method of the sprite class
to advance the frames.

I ended up rewriting my own version of the sprite class that did not
use the pyglet scheduler. Instead, sprites have an update(self, dt)
method that I call during each pass through the event loop. This
method updates the sprite's internal timer and, when appropriate,
advances the frame. I could send you the code if you like, but it is
not batch-aware.

--phillip

Tom One

unread,
Feb 8, 2011, 9:49:44 AM2/8/11
to pyglet-users
If you find that pyglet sprites are too slow for you, you could use
rabbyt sprite library, it's written in c and can be used with pyglet.

Aaron

unread,
Feb 8, 2011, 6:12:28 PM2/8/11
to pyglet-users
On Feb 8, 12:35 am, Phillip Nguyen <evil.phil...@gmail.com> wrote:
> I also had problems with animated sprites being too slow in my own
> project, where I was drawing hundreds of different animated sprites to
> the screen at once. It's been a while so I don't remember all of the
> details, but I think that I decided the slow-down was the fault of
> using clock.schedule_once() in the _animate method of the sprite class
> to advance the frames.

If it's Pyglet's own animation scheduling that's causing slowdown,
I'll definitely look at managing animation myself.

I'm wondering, to hopefully keep batch awareness and to avoid having
to get too deep inside Pyglet's code, how effective it would be to
perform animation by making assignments to a Sprite's image property.
The Sprite would have a static image representing the current frame,
which gets replaced by a new image when the animation needs to update.
Is using this image property effective?

As for Rabbyt, it doesn't seem to have animated sprites built in like
Pyglet does, so it looks like I'm going to have to handle animation
updates myself anyway. I'm also in the process of figuring out how to
actually install Rabbyt. :P

Tom One

unread,
Feb 9, 2011, 2:07:22 PM2/9/11
to pyglet-users
What's the problem with installation? What os are you using, what
version of python?

Aaron

unread,
Feb 9, 2011, 6:13:43 PM2/9/11
to pyglet-users
On Feb 9, 3:07 pm, Tom One <tae...@gmail.com> wrote:
> What's the problem with installation? What os are you using, what
> version of python?

Are you talking about Rabbyt?

Anyway, I'm using Mac OS X 10.6.6 and Python 2.6.4. This is what I get
when I try to install Rabbyt:

$ sudo python setup.py install
running install
running bdist_egg
running egg_info
creating Rabbyt.egg-info
writing Rabbyt.egg-info/PKG-INFO
writing top-level names to Rabbyt.egg-info/top_level.txt
writing dependency_links to Rabbyt.egg-info/dependency_links.txt
writing manifest file 'Rabbyt.egg-info/SOURCES.txt'
reading manifest file 'Rabbyt.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'Rabbyt.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.3-fat/egg
running install_lib
running build_py
creating build
creating build/lib.macosx-10.3-fat-2.6
creating build/lib.macosx-10.3-fat-2.6/rabbyt
copying rabbyt/__init__.py -> build/lib.macosx-10.3-fat-2.6/rabbyt
copying rabbyt/anims.py -> build/lib.macosx-10.3-fat-2.6/rabbyt
copying rabbyt/sprites.py -> build/lib.macosx-10.3-fat-2.6/rabbyt
running build_ext
pyrexc rabbyt/rabbyt._rabbyt.pyx --> rabbyt/rabbyt._rabbyt.c
building 'rabbyt._rabbyt' extension
creating build/temp.macosx-10.3-fat-2.6
creating build/temp.macosx-10.3-fat-2.6/rabbyt
gcc-4.0 -arch ppc -arch i386 -fno-strict-aliasing -fno-common -
dynamic
-DNDEBUG -g -O3 -I/Library/Frameworks/Python.framework/Versions/2.6/
include/python2.6 -c rabbyt/rabbyt._rabbyt.c -o build/
temp.macosx-10.3-
fat-2.6/rabbyt/rabbyt._rabbyt.o -O3 -fno-common -I /System/Library/
Frameworks/OpenGL.framework/Headers
In file included from /usr/include/architecture/i386/math.h:626,
from /usr/include/math.h:28,
from /Library/Frameworks/Python.framework/Versions/
2.6/include/python2.6/pyport.h:235,
from /Library/Frameworks/Python.framework/Versions/
2.6/include/python2.6/Python.h:58,
from rabbyt/rabbyt._rabbyt.c:4:
/usr/include/AvailabilityMacros.h:108:14: warning: #warning Building
for Intel with Mac OS X Deployment Target < 10.4 is invalid.
Compiling with an SDK that doesn't seem to exist: /Developer/SDKs/
MacOSX10.4u.sdk
Please check your Xcode installation
gcc-4.0 -arch ppc -arch i386 -isysroot /Developer/SDKs/
MacOSX10.4u.sdk
-g -bundle -undefined dynamic_lookup build/temp.macosx-10.3-fat-2.6/
rabbyt/rabbyt._rabbyt.o -lGL -lGLU -lm -o build/lib.macosx-10.3-
fat-2.6/rabbyt/_rabbyt.so -dynamic -L/System/Library/Frameworks/
OpenGL.framework/Libraries
ld: library not found for -lbundle1.o
collect2: ld returned 1 exit status
ld: library not found for -lbundle1.o
collect2: ld returned 1 exit status
lipo: can't open input file: /var/tmp//ccIjDjwy.out (No such file or
directory)
error: command 'gcc-4.0' failed with exit status 1

Casey Duncan

unread,
Feb 9, 2011, 6:16:45 PM2/9/11
to pyglet...@googlegroups.com
Do you have xcode installed? Note that you may need to use a custom
install option that includes the 10.4 sdk.

-Casey

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

Reply all
Reply to author
Forward
0 new messages