> but then when i uncomment the texture atlas line and have another
> 2048x2048 texture - it drops from 500fps to 40fps!!
> all other texture atlas size combinations work - only two times
> 2048x2048 gives this strange performance drop!
I'd guess that you're hitting your video RAM limit -- with two
2048x2048 textures, the driver is needing to page them in and out of
video memory within each frame.
Alex.
I think there are two general ways to proceed, depending on what your
application needs.
Case 1) You need the 2048x2048 space for texture data, but not all at
once on the screen. This would be the case if the application is a
game and the texture data contains all the animation frames for
sprites, backgrounds, etc., that appear in the game.
In this case I would proceed by dividing the data into more textures
that get used as needed. An idea is to have one texture per enemy
type. If the enemy type doesn't appear on screen, the texture can be
paged out until needed. With this method you would still get a
slowdown if lots of enemy types appeared onscreen at once, but that is
reasonable.
Case 2) You really do need the 2048x2048 space on the screen all at
once. I would proceed by resizing the texture data itself. Instead
of one 2048x2048 texture, scale the image data down by a factor of 2
to get a single 1024x1024 texture (perhaps using PIL). Then draw this
texture to the same size as previously. It won't be as crisp with the
same detail but it will be fast. This is like turning down the
"graphic detail" setting on lots of games to get your framerate up.
You should make this an option so that users with better graphics
cards get the full textures.
--
Nathan Whitehead
- Reduce the size of the textures, either by using native texture
compression (GL_ARB_texture_compression if supported), reducing the
resolution of certain textures (this could be configurable as in many
commercial games), or simply using fewer different images in your
atlas
- Reorder the textures so that swapping is minimized. Put all of you
background textures together and make sure they are drawn first, then
do another batch from the next texture atlas, etc. There will still be
swapping, but hopefully not as much. You might find that using smaller
atlases is better if you aren't going over by much.
Bottom line though is that 64MB of VRAM isn't very much these days,
something's probably got to give in the quality dept.
-Casey
Looking good. Texture compression won't really be suitable for you
game given the pixel-art style; however you may benefit from using a
lower bit depth for the texture internal format; e.g. GL_RGBA4 (4 bits
per component), GL_RGB5_A1 (5 bits per r/g/b, 1 for alpha), etc. I
haven't tried these myself, so I don't know if this makes a practical
difference on modern video cards.
Alex.
I don't know how the gameplay works, but another idea is to not clear
the graphics buffer between frame updates. I.e., draw the highly
detailed big map on the color buffer, then leave it there. If the
screen isn't moving then you don't have to redraw each frame entirely.
Just don't call glClear at the start of drawing. Then when something
happens on part of the screen, redraw just that part. You can update
nonrectangular regions using the stencil buffer, or you can change the
viewport and use scissoring to update a rectangular area. The OpenGL
guide has a chapter on this.
This might take some extra coding to calculate which parts to update.
And if most of the screen is changing it wouldn't help very much. I
can't think of any reason you couldn't use the pyglet functions to do
things still. If you're updating rectangles then you would just need
a couple glViewport and glScissor calls before the update.
--
Nathan Whitehead
Remember to disable double-buffering if you take this route.
Alex.
Given this is a more old-school sprite style game, perhaps a more old
school approach is needed.
I seriously doubt the original game redrew the entire map every frame.
More than likely it used the tried and true "dirty rectangle" approach
and only redrew what had actually changed each frame. Perhaps you
should consider the same approach, don't clear the buffer and redraw
every frame, just figure out what parts of the map actually changed
and redraw that. Even if it takes a few frames to render the whole
map, you would rarely have to do it in practice so it wouldn't matter.
I would suggest reading this interesting essay on how simcity 4
renders their cityscapes:
http://simcity.ea.com/about/inside_scoop/3d1.php
One thing they admit at the end is how much better suited 3D graphics
technology is to first-person style games than god games, since you
can naturally limit the level of detail over distances.
-Casey