[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Re: SDL 1.3 blit speed



Hi, Brian.

DR0ID and I have been discussing this particular technique. We're very intrigued by the concept. It is a brain-twister, though! I searched far and wide and haven't found any examples in any language. Would you happen to know of an example, article or book discussing it in further detail?

Gumm

On Tue, Jul 12, 2011 at 10:32 PM, Brian Fisher <brian@xxxxxxxxxxxxxxxxxxx> wrote:
One particular technique for scrolling multi-layer backgrounds (that don't have parallax or animation anyways) is to have one large surface which is big enough to cover the screen, and to treat it as a wrapping buffer (so you do 4 blits to the screen from the surface in order to get the parts of the buffer as they wrap around the edges - hope that makes sense). Then as the background scrolls, you render in the newly visible parts into the buffer from your layers (using source clipping to get just the newly visible portion rendering on top of the newly offscreen part)

It can have dramatic speed improvements compared to redrawing all layers every time because when you have a lot of layers with transparency, all that transparency gets flattened in the cache. The blit to the screen from the buffer is just a copy, it doesn't spend time on color-key or alpha blending (this technique is actually great for when you want alpha blended layers, btw, which can look better than color key).  Also, you'll have fewer blit calls as well, which means fewer native code crossings from python which are moderately slow.

...while animation and layers on top of animating characters don't work great with this technique, you can actually combine a dirty rect system with the wrapping buffer to address that, so as long as the use of the animation and the layers on top are sparsely used, you still get all the savings of not compositing the parts of the screen not affected by animation every frame.



On Tue, Jul 12, 2011 at 7:02 PM, Brian Brown <brobab@xxxxxxxxx> wrote:
That might work . . .  : )


On Tue, Jul 12, 2011 at 6:58 PM, Brian Fisher <brian@xxxxxxxxxxxxxxxxxxx> wrote:
If the layering is something that is consistent from one moment to the next, and you really have an overdraw of 3x, you can pre-combine and cache the visible parts, which could potentially make it take 1/3rd the speed (that's your goal, right?)


On Tue, Jul 12, 2011 at 6:26 PM, Brian Brown <brobab@xxxxxxxxx> wrote:
Yes, I'm only blitting the visible parts. It's the tile layering that causes 3x more blitting. (floor, carpet, and a possible wall for every tile.)
Blitting the whole 300x300 map will take a very looooong time . . .

 . . .

Okay so, will SDL 1.3 regular blitting be 3x faster?

On Tue, Jul 12, 2011 at 11:52 AM, DR0ID <dr0id@xxxxxxxxxx> wrote:
On 12.07.2011 20:12, Brian Brown wrote:
Thanks guys,
I'm not using Pyopengl. (I found it a little too hard to use.)
Pygame and SDL are working perfectly for me-- except-- I need faster blitting. That's all, I think.
I've designed my game's graphics to simply rely on the blitting of many 60x60 24-bit surfaces. (Approximately 300 to 500 blits per frame on a scrolling screen of 640x480 resolution. The game is tile based with an overlapping 3D illusion. The floor is drawn first, the "mat" second, and the characters and "blocks" sorted by distance from bottom of screen are last. Should look fantastic when graphics are finished and when the fps is higher.)

If SDL 1.3 will blit basic 24-bit surfaces (with a single colorkey) 3x faster I think my game will work quite nicely.

* I am using convert().
* I'm not using per-pixel-alpha.
* I even blit the freshly-loaded-surfaces onto a new surface to be sure the surfaces haven't inherited any unnecessary data from the png file. (I found this to significantly increase speed.)
* The whole screen is scrolling so I use pygame.display.flip().
* I think I'm using 24-bit images.
* I need a high refresh rate for high speed chases with the local wildlife . . . (bear, tigers, unicorns etc.)
* I'll have to try using surface.fill() instead of blitting . . .
* My program's code is already running at a nice speed.

Sounds like a great idea to continue programming with pygame and then later speed things up, but--

It's just a little harder to program with slow graphics --My personal policy for low stress programming is to reward myself after every day of hard work by playing the game, and it's not the most fun in slow motion.

Is there a way to convert 24-bit pygame surfaces to 8 bit RLE just to temporarily speed things up for testing?
Thanks for the great advice guys.

On Tue, Jul 12, 2011 at 6:14 AM, René Dudfield <renesd@xxxxxxxxx> wrote:
On Tue, Jul 12, 2011 at 1:59 PM, Sean Wolfe <ether.joe@xxxxxxxxx> wrote:

Dude this was a really good answer. Rrrrrespect


Indeed, good answer.

Also, are you using fast rendering techniques?
  • Using 8 bit RLE encoded surfaces for the low colour depth images
  • avoiding per pixel alpha surfaces.
  • using convert() appropriately (except not on those low colour surfaces).
  • using fill() to fill in colours instead of blit.
  • using LayeredDirty sprite group, and DirtySprite sprites to do dirty rectangle updates.
  • updating parts of the screen at the lowest refresh rate they need.  eg, displaying fps, may only need be done once every 10 frames.
  • profiled your game ( to see which parts are slow.) http://pygame.org/wiki/Profiling


SDL 1.3 is faster with opengl/direct3d surfaces.  But it's _still not finished.


cu.



Hi

Just a side note: If you have a scrolling world then blit only the visible parts, that will give you a performance boost (not sure if you do this already).

~DR0ID