GP2X Checking Whether A Sprite Is On-screen Before Drawing It


motorollin

Member
Joined
Jul 31, 2007
Messages
163
CODE
bool onScreen( sprite* s)
{
if ( s->x < camera.x - s->w ) return false;
if ( s->x > camera.x + camera.w ) return false;
if ( s->y < camera.y - s->h ) return false;
if ( s->y > camera.y + camera.h ) return false;

return true;
}

if ( onScreen( enemy ) ) enemy.show();
...



In a scrolling game, is it worth using code like the example above to check whether a sprite is within the viewable area or not before drawing it, or would the checks take as much time as just drawing it whether it can be seen or not?
 
Definately faster than a blit, so I would recommend you to check that directly in your blitting function:
CODE
void sput( SDL_Surface *source, SDL_Surface *dest, int x, int y )
{
int half_w = source->w / 2;
int half_h = source->h / 2;

if( x > -half_w && x < dest->w + half_w && y > -half_h && y < dest->h + half_h )
{
SDL_Rect pos;
pos.x = x - half_w;
pos.y = y - half_h;

SDL_BlitSurface( source, 0, dest, &pos );
}
}

(Note: this puts a surface centered on another surface as long as its not outside the surface.)
 
Yes it's better to check and avoid drawing where possible, since otherwise you are pushing a lot of pixels onto the buffer which won't even be seen! Also if you are using Alpha-blending and such it's further CPU time wasted one something that won't even be seen!

It's in the same way that you want to only keep you collision detections to the minimum number of tests as you need to do, etc.
 
Cheers guys. I've improved my onScreen function and called it before blitting and checking collisions.
 
PokeParadox said:
Yes it's better to check and avoid drawing where possible, since otherwise you are pushing a lot of pixels onto the buffer which won't even be seen! Also if you are using Alpha-blending and such it's further CPU time wasted one something that won't even be seen!
Where? Is your buffer larger than the screen?

If you have a buffer the same size as the screen and your blitter already clips to the buffer then you'd have to be drawing a LOT of sprites to see any benefit. And if you've got enough sprites for that to matter, you probably need to group them and check their "on-screen-ness" in batches, so you don't have to touch every sprite.
 
Last edited by a moderator:
Count the instructions, checking cheap, blitting expensive, usually thrift pays well on systems this size, even in pc work with SDL I've never measured but I think it's faster trimming sprites to screen and never drawing anything for it to clip. A lot faster.
 
Sphinxter said:
Count the instructions, checking cheap, blitting expensive, usually thrift pays well on systems this size, even in pc work with SDL I've never measured but I think it's faster trimming sprites to screen and never drawing anything for it to clip. A lot faster.
Sorry, I'm a little confused by your message -- are you replying to me?

What I'm saying is, the blitter has to clip to the drawing surface, because if it didn't it would write to bad places in memory. (unless it's a lower-level blitter, in which case you have to clip yourself before calling it) If the destination rect is entirely outside of the surface, it will clip to nothing and no blitting will occur. Sure, it still has to do the function call and clip to the screen internally, but that's relatively quick. Only a really, really naive blitter would clip at each pixel. (Of course, if you're clipping to a non-rectangular area that's different, but the screen is always a rectangle.)
 
Last edited by a moderator:
rabidcow said:
Sphinxter said:
Count the instructions, checking cheap, blitting expensive, usually thrift pays well on systems this size, even in pc work with SDL I've never measured but I think it's faster trimming sprites to screen and never drawing anything for it to clip. A lot faster.
Sorry, I'm a little confused by your message -- are you replying to me?

What I'm saying is, the blitter has to clip to the drawing surface, because if it didn't it would write to bad places in memory. (unless it's a lower-level blitter, in which case you have to clip yourself before calling it) If the destination rect is entirely outside of the surface, it will clip to nothing and no blitting will occur. Sure, it still has to do the function call and clip to the screen internally, but that's relatively quick. Only a really, really naive blitter would clip at each pixel. (Of course, if you're clipping to a non-rectangular area that's different, but the screen is always a rectangle.)


No, motorollin actually but I agree with everything you say, I just get the feeling from working with it there must be a bit more going on behind the scene in sdl or between before it determines which pixel is valid and which pixel is nonsense, I repeat never measured but I really think I get a better feel of performance by not letting SDL clipping do any work and blitting only trimmed visible pixels as opposed to just blittering all over and letting it decide which ones are sane to draw.
 
Last edited by a moderator:
if your clipping check is so simply, then yes
it should improve the work a bit....

but it's noticeable when u're drawing 10000 sprites at once 8)

u'd better use profiler and find true narrow places in your code

^_-[
 
Signed/unsigned checking can reduce branching.
This is an optimized implementation: bounding checking inside show() + branching reduced + loop unrolled
It would be faster if (a,B) parameters were constant :p

Anyways, as Don says this won't consume too much unless you have a high number of sprites in screen.

Another tip would be checking for bounds only if you've moved your sprite coordinates. If not, do not check it (as it's supposedly right already).

CODE


#define between(c, a, b) (unsigned((c) - (a)) <= (b) - (a))

void show_all( void )
{
int i = num_enemies;

while(--i) {
if( ! between(x, camera.x - w, camera.x + camera.w ))
continue;

if( ! between(y, camera.y - h, camera.y + camera.h ))
continue;

draw i enemy...;
}
}
 
SDL will automatically clip to only the renderable area. You are not likely to save much by making your own check if you are also using SDL.
 
Back
Top