Performace questions

Hmm,
I’m rather new to graphics in general, though I think I’m learning
SDL quite quickly (It really is pretty Simple. Good work on keeping it
that way Sam and co. ;-). Anyhow, I’ve been considering something, that
is fairly common, so I’m wondering what the fastest way to implement it
is; I have a couple of ideas;

The task I’m looking at is having a map image (that is larger than the
screen), and moving sprites around that map (to keep it simple, these
will be non-animated sprites for now).

The most obvious way I can think of doing this (though maybe not the
quickest), is to setup the screen with DoubleBuffer (although I suspect
that almost all games use DoubleBuffer, no?), load my map into one
surface, load all my sprites into another surface (keeping a seperate
list or array of SDL_Rect’s that contain the location of each sprite as
a separate rect),
blitting the visible rectangle of the map to the main screen surface
(that is hidden by doublebuff), blitting each of my sprites to the
appropriate location, and calling SDL_Flip(). And repeating this
process each time I want to render a screen.

So, I guess my question would be, what is the performace of
SDL_BlitSurface; and is there any (faster) way to deal with this than
re-blitting the map each time (e.g. if the map hasn’t moved; – if it
needs to pan, I suppose, it would need to be re-blitted, no?)

Thanks, Jeff Schmidt.

PS. Question arising from something I read recently on this list: Under
X11, can SDL give me fullscreen, double-buffering, and
hardware-accel/surfaces all at the same time?–
“Message sent by @Jeff_Schmidt

The task I’m looking at is having a map image (that is larger than the
screen), and moving sprites around that map (to keep it simple, these
will be non-animated sprites for now).

I’ll let others more practiced answer this one. :slight_smile:

PS. Question arising from something I read recently on this list: Under
X11, can SDL give me fullscreen, double-buffering, and
hardware-accel/surfaces all at the same time?

Nope. It can give you fullscreen, but if you want double-buffering and
hardware acceleration, you need to run under DirectX or the framebuffer
console.

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Sam Lantinga wrote:

PS. Question arising from something I read recently on this list: Under
X11, can SDL give me fullscreen, double-buffering, and
hardware-accel/surfaces all at the same time?

Nope. It can give you fullscreen, but if you want double-buffering and
hardware acceleration, you need to run under DirectX or the framebuffer
console.

Ouch ;-)  Considering that most ppl aren't yet running the fbcon (most ppl

I know, anyhow), and that some/most/no? other Unices don’t have the fbcon or
equivalent, this would tend to limit ones audience, wouldn’t it? Oh well; Do
you know, will future versions of XFree and the XF_DGA extensions allow this
functionality to be added to SDL/X? In the absence of double-buffer, how do
you minimize screen flicker/sprite-tearing?

    -Sam Lantinga                           (slouken at devolution.com)

Thanks,

Jeff Schmidt–
“Message sent by @Jeff_Schmidt

that almost all games use DoubleBuffer, no?), load my map into one
surface, load all my sprites into another surface (keeping a seperate
list or array of SDL_Rect’s that contain the location of each sprite as
a separate rect),
blitting the visible rectangle of the map to the main screen surface
(that is hidden by doublebuff), blitting each of my sprites to the
appropriate location, and calling SDL_Flip(). And repeating this
process each time I want to render a screen.

It depends on your particular map. If your map is small, your method
might work for you, but the most common method of doing maps
like this is not to create a huge map and load it into memory, but rather
break it up into “tiles” that are pieced together to make your map.

A simple example of this is a huge 1280x1280 map, which actually consists
of a simple 128x128 grass tile repeated 100 times.

Obviously, a single 128x128 image is much smaller than a 1280x1280
surface.

Now I doubt you will want your game to be made up of just that one tile,
but it gives you a starting place to add the additional pieces you want in
your game.–
Brian Hayward

Ouch ;-)  Considering that most ppl aren't yet running the fbcon (most ppl

I know, anyhow), and that some/most/no? other Unices don’t have the fbcon or
equivalent, this would tend to limit ones audience, wouldn’t it? Oh well; Do
you know, will future versions of XFree and the XF_DGA extensions allow this
functionality to be added to SDL/X?

Yes. :slight_smile:
Remember I mentioned that when DGA 2.0 is released, I will add a new
fullscreen video driver that uses it? :slight_smile:

See ya!
-Sam Lantinga (slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

hayward at slothmud.org wrote:

It depends on your particular map. If your map is small, your method
might work for you, but the most common method of doing maps
like this is not to create a huge map and load it into memory, but rather
break it up into “tiles” that are pieced together to make your map.

A simple example of this is a huge 1280x1280 map, which actually consists
of a simple 128x128 grass tile repeated 100 times.

Hmm, yes, I'm familiar with the tile idea.  It is the easiest way to avoid

having to repeat the same data over and over. Make a data structure that
contains a “pointer” (in this case, a SDL_Rect, as opposed to an actual
pointer) to the correct tile. But I guess my question is this: is it as fast
or faster to blit each tile individually than to “pre-compose” a portion of
your map into a surface? What I had in mind when I wrote my previous email
was that you take a data file, which has your tile information and, say, a
grid of tilenumbers that represents your map; say your map is 20 screens tall
and 20 screens wide; obviously, you’re not going to load the entire map into
one huge surface; but would you get any performace advantage from loading,
say, 4 screens of data at a time into a surface and panning around that
surface until your character approaches one of the edges?


Brian Hayward

Cheers,

Jeff–
“Message sent by @Jeff_Schmidt

Sorry to reply to myself, but here goes. . .

Jeff Schmidt wrote:

hayward at slothmud.org wrote:

It depends on your particular map. If your map is small, your method
might work for you, but the most common method of doing maps
like this is not to create a huge map and load it into memory, but rather
break it up into “tiles” that are pieced together to make your map.

A simple example of this is a huge 1280x1280 map, which actually consists
of a simple 128x128 grass tile repeated 100 times.

I went back to my original message, and thinking about it, I realized that the
tile system might be quite a bit faster in the end. Cause if I move a sprite,
instead of re-blitting the visible portion of the map, I suppose, if my map
doesn’t need to scroll, that all I have to do is re-blit the tile the sprite used
to be on top of, and re-blit the sprite at its new location. Less screen
re-drawing. :wink: Thanks for your comments.–
“Message sent by @Jeff_Schmidt

Hmm, yes, I'm familiar with the tile idea.  It is the easiest way to avoid

having to repeat the same data over and over. Make a data structure that
contains a “pointer” (in this case, a SDL_Rect, as opposed to an actual
pointer) to the correct tile.

Depending on how many tiles you have, you might be better of using an
unsigned byte that indexes into an array of SDL_Surface’s, rather than
pointers. Bytes are small. Pointers are a few times larger. :slight_smile:

-bill!

Hmm, yes, I’m familiar with the tile idea. It is the easiest way to avoid
having to repeat the same data over and over. Make a data structure that
contains a “pointer” (in this case, a SDL_Rect, as opposed to an actual
pointer) to the correct tile. But I guess my question is this: is it as fast
or faster to blit each tile individually than to “pre-compose” a portion of
your map into a surface?

If you have a 128x128 tilesize and are blitting it to a 640x480 display,
you do under 20 seperate tile blits.

grid of tilenumbers that represents your map; say your map is 20 screens tall
and 20 screens wide; obviously, you’re not going to load the entire map into
one huge surface; but would you get any performace advantage from loading,
say, 4 screens of data at a time into a surface and panning around that
surface until your character approaches one of the edges?

Pre-composing your ‘larger than the screen’ area will probably end up in
the same number of pixel’s blitted, but in one operatin. Conceivably it’s
quicker, but it’s probably not very noticeable. And it will use quite a
bit more memory.

Are you considering these to be a single surface, 4 screens? Basically
like using a 4screen region as a “tile”?
What if you were in the corner between 4 different "pre-composed"
4screen submaps? Wouldn’t you then have to have the equivilant of 16
screens worth of data in memory?

Do what I did. Test all of your ideas and see if you really get a
noticeable performance increase. You can see how nasty loading large
images into memory is as well. :)–
Brian

I went back to my original message, and thinking about it, I realized that the
tile system might be quite a bit faster in the end. Cause if I move a sprite,
instead of re-blitting the visible portion of the map, I suppose, if my map
doesn’t need to scroll, that all I have to do is re-blit the tile the sprite used
to be on top of, and re-blit the sprite at its new location. Less screen
re-drawing. :wink: Thanks for your comments.

The ‘redrawing’ idea can be done with your idea as well as mine. Have two
surfaces for your sprite. One actually holds the sprite. The other is
updated with a copy of the area that the sprite will go on, before the
sprite is placed there. Then you can erase the sprite, grab the next
backdrop, re-blit the sprite when it moves.–
Brian

Hmm, yes, I'm familiar with the tile idea.  It is the easiest way to avoid

having to repeat the same data over and over. Make a data structure that
contains a “pointer” (in this case, a SDL_Rect, as opposed to an actual
pointer) to the correct tile. But I guess my question is this: is it as fast
or faster to blit each tile individually than to “pre-compose” a portion of
your map into a surface? What I had in mind when I wrote my previous email
was that you take a data file, which has your tile information and, say, a
grid of tilenumbers that represents your map; say your map is 20 screens tall
and 20 screens wide; obviously, you’re not going to load the entire map into
one huge surface; but would you get any performace advantage from loading,
say, 4 screens of data at a time into a surface and panning around that
surface until your character approaches one of the edges?

That depends on a few things. First of all how time consuming is your
rendering loop, if you are just blitting images to the screen with no
modification, then don’t buffer, since there will be a pause when you
reach the edge of the buffer and need to render the new one. If your
loop is expensive, then buffer. The general rule for these thing is to
do it the simple/elegant way first, and only change it if your profiler
tells you it is too slow.

Stuart

hayward at slothmud.org wrote:

I went back to my original message, and thinking about it, I realized that the
tile system might be quite a bit faster in the end. Cause if I move a sprite,
instead of re-blitting the visible portion of the map, I suppose, if my map
doesn’t need to scroll, that all I have to do is re-blit the tile the sprite used
to be on top of, and re-blit the sprite at its new location. Less screen
re-drawing. :wink: Thanks for your comments.

The ‘redrawing’ idea can be done with your idea as well as mine. Have two
surfaces for your sprite. One actually holds the sprite. The other is
updated with a copy of the area that the sprite will go on, before the
sprite is placed there. Then you can erase the sprite, grab the next
backdrop, re-blit the sprite when it moves.


Brian

Somewhere along the line, my prose got muddy as I was cognate-ing ;-)

Basically, above, I was saying that “your right,” as I realized the advantage that the
tile system that you had suggested would give me. Namely, that I only have to re-blit
map tiles that are being “uncovered”, as opposed to re-blitting the entire screen
everytime I move sprites. Now, when the character moves far enough over on the screen
that I have to start “panning” my map, I would have to re-blit all the visible
portions of the map with either system, so tiles is “one-up” on advantages so to
speak. :wink:

Thanks,

Jeff–
“Message sent by @Jeff_Schmidt

Can’t remember the technical term for the technique but…
Before you draw any of you sprites you can save the area thats gonna be
modified into a surface the same size as the sprite then draw the sprite.
When the sprite moves, copy the saved surface back to its old location.

Long live the confused,
Akawaka.–
Bother, said Pooh, as he tried to install OS/2.

On Fri, 28 Jan 2000, Jeff Schmidt wrote:

I went back to my original message, and thinking about it, I realized that the
tile system might be quite a bit faster in the end. Cause if I move a sprite,
instead of re-blitting the visible portion of the map, I suppose, if my map
doesn’t need to scroll, that all I have to do is re-blit the tile the sprite used
to be on top of, and re-blit the sprite at its new location. Less screen
re-drawing. :wink: Thanks for your comments.

Jeff Schmidt wrote:

hayward at slothmud.org wrote:

It depends on your particular map. If your map is small, your method
might work for you, but the most common method of doing maps
like this is not to create a huge map and load it into memory, but rather
break it up into “tiles” that are pieced together to make your map.

A simple example of this is a huge 1280x1280 map, which actually consists
of a simple 128x128 grass tile repeated 100 times.

Hmm, yes, I'm familiar with the tile idea.  It is the easiest way to avoid

having to repeat the same data over and over. Make a data structure that
contains a “pointer” (in this case, a SDL_Rect, as opposed to an actual
pointer) to the correct tile. But I guess my question is this: is it as fast
or faster to blit each tile individually than to “pre-compose” a portion of
your map into a surface? What I had in mind when I wrote my previous email
was that you take a data file, which has your tile information and, say, a
grid of tilenumbers that represents your map; say your map is 20 screens tall
and 20 screens wide; obviously, you’re not going to load the entire map into
one huge surface; but would you get any performace advantage from loading,
say, 4 screens of data at a time into a surface and panning around that
surface until your character approaches one of the edges?

Sorry this reply is so late, I have had friends coming over like crazy
and havn’t had time to respond to stuff that I wanted to.

I actually did a program a while back for DOS using Allegro, it was a
soccer game with little cars that ran around on the fields. two images.
One was half of the area where the goal is so that when mirrored beside
itself it would form a complete goal. The other was the middle of the
field with the little kickoff circle thingie (soccer’s not my sport.
hehe) that when mirrored would complete the circle. The field was made
up of six actual images, just loaded from two. (The two for the top
goal, the two for the center and the two for the bottom goal) I don’t
know why I did it this way, but I did, and it worked quite well on my
90mhz until I tryed to play it on a 400mhz!
The game itself still essentially used a tile based engine, just with
huge 640x480 tiles. It wasn’t even optimized, really, that is I drew the
tiles every frame (not all the tiles, just the ones in the screen).
I’m not saying this is the best way to do it, but it worked for me. It
really depends on the game you plan on making I guess.

Jeff Schmidt wrote:

hayward at slothmud.org wrote:

It depends on your particular map. If your map is small, your method
might work for you, but the most common method of doing maps
like this is not to create a huge map and load it into memory, but rather
break it up into “tiles” that are pieced together to make your map.

A simple example of this is a huge 1280x1280 map, which actually consists
of a simple 128x128 grass tile repeated 100 times.

Hmm, yes, I'm familiar with the tile idea.  It is the easiest way to avoid

having to repeat the same data over and over. Make a data structure that
contains a “pointer” (in this case, a SDL_Rect, as opposed to an actual
pointer) to the correct tile. But I guess my question is this: is it as fast
or faster to blit each tile individually than to “pre-compose” a portion of
your map into a surface? What I had in mind when I wrote my previous email
was that you take a data file, which has your tile information and, say, a
grid of tilenumbers that represents your map; say your map is 20 screens tall
and 20 screens wide; obviously, you’re not going to load the entire map into
one huge surface; but would you get any performace advantage from loading,
say, 4 screens of data at a time into a surface and panning around that
surface until your character approaches one of the edges?

OOPS! Sorry I mis-read your post and responded with an unhelpful answer
before.

John Garrison wrote:

OOPS! Sorry I mis-read your post and responded with an unhelpful answer
before.

Actually, in it's own way, it _is_ helpful.  See, what I'm working on is porting

a GPL’d game engine called Verge (www.verge-rpg.com – right now the site is not up,
but hopefully will be back soon) that currently is written for DOS using DJGPP to
win32/*nix using SDL. For the most part, I will be working with the existing Verge
code-base, and therefor the type of design decisions we have been discussing have
(mostly) already been made by the original Verge developers. But, at the same time,
I will probably be making some modifications to the engine, and want to keep an eye
out for playability issues. Verge has always had as one of it’s goals that games
made with it would be playable on older 486 and pentium machines. I’ll admit, w/o
any hesitation, that I am rather new to games programming (actually, kind of new to
programming in general), and, I guess, I just still cant grasp how fast that (even
older) cpu’s are at doing things. I have heard, fairly often, that screen drawing
is actually the slowest bottle-neck for most games, not the CPU, so what I need to
do is just start playing around and seeing what works.

Verge is tile-based as it currently stands, so I will change it as little as I can
get away with. I guess it just still AMAZES me, even now, after having used
computers for 10 years, how fast they are [I guess I’ve become too accustomed to slow, bloated software like MS Word, that gives a fast machine the illusion of being slow :wink: (tangential rant – have you ever noticed how really _fast_ WordPerfect 5.1 for DOS was? Even on a 386 it was snappy and responsive)]; It still amazes me,
after playing computer games for years, that computers can give the user (usually)
the illusion of moving around in a world, when that world, and it’s characters, are
being drawn rectangle-by-rectangle (or even pixel-by-pixel for truly massochistic
programmers :wink: on the screen for every frame, and you need approximately 20(?) fps
to give a fairly smooth, lifelike animation (while not being incredibly slow), so
the cpu is really performing millions of operations per second.

Anyhow, sorry for sending such a long-winded message to the list. And thank you,
Everybody who responded, for your insights.

Jeff Schmidt.

P.S. Question to the list maintainers: how come I don’t get email that are sent to
the list until an hour after they are sent? Is the number of people subscribed to
the list just really large?–
“Message sent by @Jeff_Schmidt

Can’t remember the technical term for the technique but…
Before you draw any of you sprites you can save the area thats gonna be
modified into a surface the same size as the sprite then draw the sprite.
When the sprite moves, copy the saved surface back to its old location.

I believe it’s called “saveunders.” I think. :slight_smile:

-bill!
(Who wishes PC graphics hardware had support for REAL sprites… like those
on the old Atari 8-bit, C=64 and C=Amiga)

William Kendrick wrote:

(Who wishes PC graphics hardware had support for REAL sprites… like those
on the old Atari 8-bit, C=64 and C=Amiga)

What, hardware acceleration doesn’t count? (the 2D kind, of course, 3D
is a whole other thing)–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/

William Kendrick wrote:

(Who wishes PC graphics hardware had support for REAL sprites… like those
on the old Atari 8-bit, C=64 and C=Amiga)

What, hardware acceleration doesn’t count? (the 2D kind, of course, 3D
is a whole other thing)

Good point, this curiosity came to mind for me as well.

Were they just hardware blitting and hw transparent blitting?
Or were there any more ‘sprite’ specific hardware routines? If so, what
kind?–
Brian

hayward at slothmud.org wrote:

What, hardware acceleration doesn’t count? (the 2D kind, of course, 3D
is a whole other thing)

Good point, this curiosity came to mind for me as well.

Were they just hardware blitting and hw transparent blitting?
Or were there any more ‘sprite’ specific hardware routines? If so, what
kind?

There is no sprite specific stuff that I know of. Just disgustingly fast
colorkey blitting (take the fastest SDL blit and make it 10-20 times
faster, depending on the card).–
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/