scenes.py
+from pyglet import image
-self.tile = engine.resource.load('grass1.png')
+self.tile = image.load('grass1.png')
It works at 96FPS (I also removed fps limit and vsync), so I bet the problem
is related to your resource loader. Anyway, with pyglet I get far more FPS,
so there is something wrong.
Besides, may be pyglet 1.1 has what you need:
http://pyglet.org/doc/1.1/api/pyglet.resource-module.html
> --
> No virus found in this incoming message.
> Checked by AVG Free Edition.
> Version: 7.5.516 / Virus Database: 269.21.5/1314 - Release Date:
> 05/03/2008 18:38
>
>
I only took a few seconds to look at your code, but I'm pretty sure
it's because you're calling blit 247 times per frame. The first
optimization is to use a display list (it will at least save you all
those excess function calls). I think there is `batch' feature in
pyglet which might help, but I haven't looked into it much yet - so
take my advice with a grain salt there. There is another much more
involved optimization that entails ordering your renderable objects by
driver state - but that would require overriding or monkey-patching
blit on Texture.
Cheers,
--
\\\\\/\"/\\\\\\\\\\\
\\\\/ // //\/\\\\\\\
\\\/ \\// /\ \/\\\\
\\/ /\/ / /\/ /\ \\\
\/ / /\/ /\ /\\\ \\
/ /\\\ /\\\ \\\\\/\
\/\\\\\/\\\\\/\\\\\\
d.p.s
Yes, it seems the 247 blits are killing fps, too.
I did say that something was wrong, but I get the same 96 FPS with this
simple test code, and reducing the range increases drastically fps:
#Grass Test
#------------------------------------------
from pyglet import window,clock,image
from pyglet.gl import *
test=image.load('grass1.png')
win = window.Window(width=800,height=600,vsync=False)
clo = clock.Clock()
clo.set_fps_limit(0)
def render():
global test
for x in range(13):
for y in range(19):
test.blit(x*60,y*30)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
while not win.has_exit:
glClear(GL_COLOR_BUFFER_BIT)
win.dispatch_events()
dt=clo.tick()
render()
win.flip()
win.set_caption("FPS="+str(int(clo.get_fps())))
Yes, it seems the 247 blits are killing fps, too.
I did say that something was wrong, but I get the same 96 FPS with this
simple test code, and reducing the range increases drastically fps:
I always use -O, that makes the difference.
It is due to opengl error checking.
> is related to your resource loader.
I was wrong, I tried your original code without optimization, and my
version with it.
Consider the differences between your hw specs and use something as a
benchmark - what kind of framerates are you getting on the examples,
etc.
The code is remarkably short and easy to find in the pyglet.image module.
> Even a very trivial implementation of
> glBegin/2 triangles/glEnd per sprite should still do far better than
> 13fps with under 300 sprites.
Not when you're running Python code through ctypes.
Richard
There's nothing wrong with blit if you're blitting one thing. The
reason it's inefficient for 100s of things on the other hand, is for
two reasons:
1. Redundant driver state enabling/disabling for textures
2. Functional call overhead
I worked around 1 before new features now available in pyglet by
monkey patching blit and grouping blittable objects. This brought me
from <100fps to around 200fps with a few hundred objects. Driver
state enabling/disabling is expensive.
Regarding 2, if you have a large group of N objects that don't move
relative to one another, the easiest optimization is to use a display
list, reducing N function calls to 1. I applied this to the Juan's
code and increased the framerate from ~12FPS to ~100FPS on my system:
> All I'm worried about is giving people
> the false impression that they can't expect blit() to perform
> reasonably, when it's clear that if you just run with the -O flag set,
> it'll more than likely be fine.
You are really expecting too much out of the -O flag.
> (I get about 120fps with 250 blits per
> frame.)
Are you claiming that the demo ran at ~13FPS on your machine and then
you enabled the -O flag and it runs ~120FPS?
Sure, my intention is simply to inform programmers that if performance is an
issue then blit() isn't the best way to go about things.
> (I get about 120fps with 250 blits per frame.)
That's considerably different from the 13FPS for 300 sprites you quoted
above :)
Richard
Please don't forget that pyglet's speed changes pretty dramatically with -O
turned on due to the removal of glGetError() after every OpenGL call.
Richard
You are comparing apples with oranges here.
> I'm not particularly interested in discussing the different ways of
> optimising OpenGL at this point, because I know all that. What matters
> to me is that we don't force the typical guy who just wants to draw
> some sprites down into display list/VBO hell.
Please don't describe pyglet.sprite as "VBO hell" until you've looked at it.
Richard
Yes, I'm aware of that ;)
I guess I was just trying to point out that tarring all VBO usage with the
brush of "it's hell" is not giving the nice Pythonic interfaces that Alex has
written (both pyglet.graphics and pyglet.sprite) a fair go :)
Richard
http://www.lighthouse3d.com/opengl/displaylists/
This is my fault, I haven't written new chapters in the Programming
Guide covering sprites and the new graphics API. Sprites are batched
and grouped according to the order you want them drawn in. That is,
all sprites in a given group in a batch will be drawn in an
indeterminate order. To have some sprites drawn in front of some
other sprites, these two groups of sprites would need to belong to
separate groups (or batches). A batch groups drawing operations
(calling batch.draw() draws all sprites/graphics in all groups in that
batch). Texture and other state sorting is handled automatically, and
small images are automatically bundled into larger textures (to
minimise state changes) when using the new resource API.
For examples, see examples/noisy/noisy.py for a simple use (one batch,
no groups), and examples/astraea/astraea.py for a more complex use
(using multiple groups and batches).
Alex.