Optimizing code?

Started by
2 comments, last by Antheus 16 years, 2 months ago
Greetings, I followed the "premature optimization is the root of all evil" saying and left my optimization for the last. So I profiled my code to see what was getting called the most... and guess what? GetPixel() was at the top of the list! It is my understanding that the GetPixel function from the SDL docs isn't very fast, but my game really needs that to be playable. I use GetPixel for two things (actually it's more, but these two are in the main loop): 1) Check if an object is standing on the terrain. These objects start out at the top of the screen and fall until they hit the terrain, this is when the first player gets his turn. But I must constantly check for this since the terrain can be destroyed at any time. 2) Check if the bullet hit a piece of terrain. I thought of representing the terrain as an array if booleans and use that instead of the actual terrain bitmap for collision checking, what do you say about doing this? Thank in advance.
Advertisement
Without knowing the specifics of your API, things like GetPixel are usually slow because they generally work thusly:

1) Lock the Video Surface, so nothing else can be drawn to it.
2) If the surface is in VRAM, copy the whole thing to system RAM.
3) Lookup the contents of the pixel.
4) If the surface was in VRAM, copy it back.
5) Unlock the Video surface.

Whatever the sequence of events which happen are, they are done for *each* call to GetPixel, which is why it's so slow. Fundamentally, looking up a pixel should be no more costly than indexing into a 2D array, its the locking/unlocking and potential copy that kill you.

If the above holds true in your case, there are a few things you can do. If your API provides you with Lock/Unlock methods which give you access to a raw buffer, you can use them to lock the surface, grab its pointer and do all your lookups in one go. This means you'll only do the expensive parts of the operation once per frame which should be a huge win.

If that's not the case, you'll want to look into ways to reduce the number of times you call GetPixel. In your case, this probably means only checking objects when terrain is destroyed, and only check the objects that are affected by the destroyed terrain.

As for your idea to have a parallel terrain array in ram, this may be a win if GetPixel is slow due to the Lock/Copy/Copy/Lock issue. If you can gather all your terrain tests for one (or a few) mass checks, then the method above is probably preferable if your API provides manual Locking. If it does not, or you cannot easily group large batches of terrain tests, then the parallel terrain array is probably your best bet.

throw table_exception("(? ???)? ? ???");

I am not sure why you need GetPixel for collision but you can always lock the surface then look up the pixel via the SDL_LockSurface, surface->pixels, then SDL_UnlockSurface. remember when accessing the buffer use y*surface->pitch to get the start of the line, not y*w*bytesize.

I dont see a GetPixel in the docs and never heard of that func. if you dont have the chm help file i highly recommend grabbing it http://www.libsdl.org/docs.php

why are you using GetPixel? if your obj drops from the screen how do you track it? and can you use that data to track the collision instead of testing for pixels?
<SkilletAudio> Your framerate proves your lack of manhood
Quote:Original post by SeeForever

1) Check if an object is standing on the terrain. These objects start out at the top of the screen and fall until they hit the terrain, this is when the first player gets his turn. But I must constantly check for this since the terrain can be destroyed at any time.

2) Check if the bullet hit a piece of terrain.


Even back in the old days getPixel anything was too slow - and then there was no shared memory.

Games that rely on this principle exploited the fact that they had access to very video memory in some raw manner, allowing these tests to be performed at same rate as other memory access (really really fast).

Quote:I thought of representing the terrain as an array if booleans and use that instead of the actual terrain bitmap for collision checking, what do you say about doing this?


Accessing video memory isn't an option anymore, unless you keep your image in system memory, and render the bitmap completely on each pass. That is likely to be too slow.

Keeping a shadow copy in memory is your best bet. Note that you don't need to keep complete image. All you need is a black/white mask.

Other way is to test for collisions against sprites (rectangles), and then perform collision test on sprite only. This may be even faster.

This topic is closed to new replies.

Advertisement