SDL Optimizations?
I'm currently using my 600Mhz P3 laptop with no 3d card to develop an RTS in SDL. If I start drawing units or the HUD on top of the terrain that's already there the frame rate drops below what I have it locked at (30). I've modified the drawing function to not draw terrain where the HUD is, but the mini map and large amounts of units are still bogging it down. I think part of the problem is the way I draw the mini map. Right now I draw 4096 (64x64 map) sprites that are 2x2 pixels each. If I remove the mini map it boosts the FPS by about 5. I haven't tried it yet, but would setting individual pixels be faster (this game works with both SDL and OpenGL, so I'd have to write a setPixel function or something that would support both)? Can anybody recommend any other optimizations that might help?
Quote:
Original post by Pipo DeClown
Pre-blit the minimap on to a surface, blit that surface in the game.
Maybe I'm missing something, but wouldn't this be just as slow? It's not like I flip the screen in between every blit, so why would it matter which surface I blit the 2x2 sprites to?
Quote:
Original post by kbranch Quote:
Original post by Pipo DeClown
Pre-blit the minimap on to a surface, blit that surface in the game.
Maybe I'm missing something, but wouldn't this be just as slow? It's not like I flip the screen in between every blit, so why would it matter which surface I blit the 2x2 sprites to?
If you pre-blit, like when you load the map, or even every 2 seconds, you don't have to blit the 4096 surfaces. If I understand your problem correctly..
Blitting one big surface is faster than per-pixel. SetPixel functions are SLOOOW, golden rule in all APIs.
Quote:
Original post by Pipo DeClown
If you pre-blit, like when you load the map, or even every 2 seconds, you don't have to blit the 4096 surfaces. If I understand your problem correctly..
The problem is that the mini map also shows units, which are constantly moving. I suppose I could have the map update less often.
Only updating the areas that have changed as is suggested above would also work, but that's easier said than done.
It's not that hard. If your units are moving they propably won't change their position quite often in the scale of the mini-map. I also assume that the minimap has a fixed background and you only draw the units on top of it (otherwise you'd have 4096 units in your game which would be quite a bunch of them[smile]).
So you could even use the dirty rectange method for the mini-map and blit the map as a whole, too like Pipo suggested.
So you could even use the dirty rectange method for the mini-map and blit the map as a whole, too like Pipo suggested.
You have to remember, at 30 FPS, people don't mind units on the minimap to move a bit slower than in the game. If you shove some work to the next frame(s), you'll get a smoother app.
I second Pipo's suggestion - you can simply spread the mini-map update over some frames, updating only a few units each time. If you want to be extra-l33t you can dynamically update the number of processed units per frame based on the last few frame times. This way you use all the CPU power that you can get while keeping the game running smoothly on less powerful hardware.
Thanks for the suggestions. I ended up only having it update the map if something has changed. It now runs at about 30 FPS with the mini map and a few units on the screen.
I still have the problem with it slowing down if there are lots of units on the screen at once, though. This time it's slowing down because it's blitting some areas twice, not because I'm doing an insane number of blits each frame. Is there a way to speed up blitting?
I still have the problem with it slowing down if there are lots of units on the screen at once, though. This time it's slowing down because it's blitting some areas twice, not because I'm doing an insane number of blits each frame. Is there a way to speed up blitting?
When you mentioned that "this game works with both SDL and OpenGL", does that mean you are using SDL to blit, or are you using OpenGL? With a 600Mhz P3 laptop with no 3d card, I can't say whether it would be better to use SDL for blitting or rely on OpenGL Software routines and just work in Ortho mode. I have a 1.4 Ghz Pentium M laptop with an integrated graphics card, and my performance is near equal after trying the same test using OpenGL with ortho mode and normal SDL_BlitSurface routines. I would assume that normal SDL blitting would be faster on your machine however.
If you are passing the SDL_OPENGLBLIT flag to SDL_SetVideoMode() in SDL, then I heard that this can harm performance, but I honestly haven't tried it out myself.
Other things you can try which have sped the game I'm working on that's in SDL:
1) Make sure you convert all the SDL_Surface* to the current display format using the function: SDL_Surface* = SDL_DisplayFormat( SDL_Surface* );
2) When using SDL_SetVideoMode(int,int,int,int); make the last argument contain the flag SDL_ANYFORMAT, so SDL does not create a 'shadow surface', which can cut blitting performance in half or more on some machines
3) Try adjusting the display of your monitor to 16-bit when passing the SDL_ANYFORMAT flag. My game runs at 125 fps in 32-bit, and 250 fps in 16-bit.
4) Instead of calling SDL_Flip(SDL_Surface*);, you can call SDL_UpdateRect(SDL_Surface*, 0, 0, 0, 0); instead. I got a small performance increase from this one.
You may have been doing all of the above, and if you have, you can always look at the SDL source and you'll see a lot of checks that they do that you may not need. I realize some people may consider this micro-optimization, but you could really strip down the SDL Blitting Routines to the point we're there almost only calling the DirectDraw functions (assuming you're using windows). I also believe that in SDL_BlitSurface there are calls to SDL_UpperBlit and SDL_LowerBlit and calling one of those can slighly speed up your blits as long as you're sure which one to call for your game. As long as you can read C, then you should be able to determine what you should do to gain a speed increase from using the appropriate function.
Finally, if you're doing any Color-Keying or Alpha Blending on the surface, these two (especially the Alpha Blending) can slow SDL's blitting routines quite a bit, so I would try to eliminate them on all surfaces that you can.
If you are passing the SDL_OPENGLBLIT flag to SDL_SetVideoMode() in SDL, then I heard that this can harm performance, but I honestly haven't tried it out myself.
Other things you can try which have sped the game I'm working on that's in SDL:
1) Make sure you convert all the SDL_Surface* to the current display format using the function: SDL_Surface* = SDL_DisplayFormat( SDL_Surface* );
2) When using SDL_SetVideoMode(int,int,int,int); make the last argument contain the flag SDL_ANYFORMAT, so SDL does not create a 'shadow surface', which can cut blitting performance in half or more on some machines
3) Try adjusting the display of your monitor to 16-bit when passing the SDL_ANYFORMAT flag. My game runs at 125 fps in 32-bit, and 250 fps in 16-bit.
4) Instead of calling SDL_Flip(SDL_Surface*);, you can call SDL_UpdateRect(SDL_Surface*, 0, 0, 0, 0); instead. I got a small performance increase from this one.
You may have been doing all of the above, and if you have, you can always look at the SDL source and you'll see a lot of checks that they do that you may not need. I realize some people may consider this micro-optimization, but you could really strip down the SDL Blitting Routines to the point we're there almost only calling the DirectDraw functions (assuming you're using windows). I also believe that in SDL_BlitSurface there are calls to SDL_UpperBlit and SDL_LowerBlit and calling one of those can slighly speed up your blits as long as you're sure which one to call for your game. As long as you can read C, then you should be able to determine what you should do to gain a speed increase from using the appropriate function.
Finally, if you're doing any Color-Keying or Alpha Blending on the surface, these two (especially the Alpha Blending) can slow SDL's blitting routines quite a bit, so I would try to eliminate them on all surfaces that you can.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement