hi,

If you just want to make a game, rather than an engine/library, it
might be better to just go with pygame Surfaces.  But if messing
around with engines, and opengl is more your idea of fun...

There's a number of threads on the mailing list about making a fast
tiling engine.


On Sun, Mar 28, 2010 at 11:29 PM, Wakefield, Robert
<[email protected]> wrote:
> Do you have any recommendation for the best way to get an OpenGL engine 
> running, especially going Pygame surface to OpenGL texture?  I'd like to 
> preserve platform-independent .py files or executables if possible.
>
> I had previously coded a simple engine with OpenGL/C++, and trying to get 
> textures from LibPNG or the like proved to be a headache even on different 
> machines, let alone a separate OS.
>
> As a side note regarding profiling, I had code profiled previously and had 
> been trying to optimize the loop based on that, but the results were 
> misleading.  The profiler said I had spend ~1.3 of 5 seconds in the loop 
> function and the rest in blit(), but I copied the loop function else without 
> the blit and its profile usage went down to ~0.3s.
>
> So the message is to check twice when you're profiling ;)  At least I know 
> the problem is definitely blit().
> ________________________________________
> From: [email protected] [[email protected]] On Behalf Of 
> Casey Duncan [[email protected]]
> Sent: Sunday, March 28, 2010 3:13 PM
> To: [email protected]
> Subject: Re: [pygame] blit speedup
>
> On Mar 28, 2010, at 12:24 PM, Wakefield, Robert wrote:
>
>> I've made a tiling engine where tiles are stored as list of subsurfaces from 
>> a texture surface, and the game map is stored as a list of tile indices.  
>> The problem is that I'm ending up with some slowdown even at low 
>> resolutions.  I was wondering if anyone's run into this before and could 
>> offer suggestions.  The code I have in the map draw() function is:
>>
>>    for i in self.tiledata: # i is an integer, tiledata is a standard list 
>> right now, will convert to an array for speed as the next step
>>        surf = dat[i]
>>        sys.screen.blit(surf, (i, i)) # I would use real coordinates, the i, 
>> i is just for speed testing
>>
>> In particular:
>>    (a.) is there a way to speed up surface.blit()?  I've already used 
>> surface.convert(), and from some of the tutorials hardware surfaces sound 
>> problematic.
>>    (b.) Is there a way to call the blit function from inlined C code?  I've 
>> seen the SciPy.blitz examples showing a massive speedup on similar loops by 
>> doing this.
>
> Before worrying about specific optimizations you should profile (run with 
> `python -m cProfile` etc). If you have already identified that blitting is 
> the most expensive thing, then speeding up the things around it (using arrays 
> instead of lists, which btw may not be faster at all), or moving the loop 
> itself into C will only help you a little.
>
> One approach I like to take is to look at the thing you plan to optimize and 
> measure how much of the time is being spent there. Then compare the total 
> time begin spent on everything to the total time that would be spent on 
> everything if you could reduce the cost of the optimization target to zero. 
> Sometimes the savings, even with infinite optimization, is not worth the 
> bother.
>
> So if blit is truly your bottleneck, and that would not be entirely 
> surprising, your choices are:
>
> 1. Make each individual blit faster
> 2. Do fewer blits (ideally zero ;^)
>
> You only have so much ability to affect #1. This involves lining up the stars 
> so that each blit does as little work as possible. Angles of attack here 
> include things mentioned like hardware surfaces, resolution, convert(). Also 
> individual surface size is a big factor (bigger or smaller could be faster). 
> Also, are you running full-screen or in a window? That can make a big 
> performance difference. What about screen color depth? What about alpha 
> blending? less is more here.
>
> You have more direct control over #2. Maybe you can use scroll instead of 
> blit, then clean up and parts where foreground objects are? Maybe you can use 
> bigger tile surfaces, or etc.
>
> In my experience for games where the entire screen must be redrawn each frame 
> (e.g. many scrollers) pygame's cpu blitting is often not fast enough. You may 
> want to consider using OpenGL, or and OpenGL-based tile engine to get the 
> performance you want.
>
> -Casey
>

Reply via email to