Optimization

Jonathan Miller wrote:

In my game I’m going to have a multilevel background. So that as you walk
along, the elements of the background scroll at different speeds giving
you that wonderful Super Nintendo-esque Almost 3D look. So, any how I’m
trying to decide how I should do this. Currently I’m reblitting everything
every time anything changes, and this is really killing the frame rate.

My game does this at about 40 fps software rendering on my 333. That’s a
reasonable framerate for software rendering, under Windows with DirectX I get
some insanely high framerate. Don’t have time to explain how it works right
now, I’ll just refer you to my code, which isn’t commented yet, so it may not
be of much help :-\

http://www.Nayzak.com/~jerryma/rival/iox.html--
-= aaron p. matthews
-= rivalgames
-= http://www.rivalgames.com

As I said before I’m trying to write a run and jump, and I’ve run into
another problem. I don’t know if it’s something that’s really list
relavent, but, what the hey, I’ll askit anyway.

In my game I’m going to have a multilevel background. So that as you walk
along, the elements of the background scroll at different speeds giving
you that wonderful Super Nintendo-esque Almost 3D look. So, any how I’m
trying to decide how I should do this. Currently I’m reblitting everything
every time anything changes, and this is really killing the frame rate.

So what are my options, how can I make this faster? I can put up a tar
ball of my little game if anyone actually wants to take the effort to look
at it, and make any suggestions.

Thanks

– Jonathan

The biggest thing I’ve discovered is to always use SDL_DisplayFormat
on surfaces before you try to blit with them (just once after loading
them into memory is enough, unless you muck with them after that).
That got my frame rate to jump from ~4 to ~18 (very unoptimized code).
If you are already doing that then you should probably go ahead and
put a tarball up on the web somewhere for some peer review.

Phoenix Kokido
members.xoom.com/kokido
@Wes_Poole

Jonathan Miller wrote:> As I said before I’m trying to write a run and jump, and I’ve run into

another problem. I don’t know if it’s something that’s really list
relavent, but, what the hey, I’ll askit anyway.

In my game I’m going to have a multilevel background. So that as you walk
along, the elements of the background scroll at different speeds giving
you that wonderful Super Nintendo-esque Almost 3D look. So, any how I’m
trying to decide how I should do this. Currently I’m reblitting everything
every time anything changes, and this is really killing the frame rate.

So what are my options, how can I make this faster? I can put up a tar
ball of my little game if anyone actually wants to take the effort to look
at it, and make any suggestions.

Thanks

– Jonathan

The biggest thing I’ve discovered is to always use SDL_DisplayFormat
on surfaces before you try to blit with them

Yeah, I’m already doing that.

If you are already doing that then you should probably go ahead and
put a tarball up on the web somewhere for some peer review.

Well anyone who’s kind enough to visit:
www.kludge.org/dirty-monkey-0.0.1.tar.bz2
or
www.kludge.org/dirty-monkey-0.0.1.tar.gz

will find a copy of the code. Just type make and pray everything
works.

Thanks again,

– JonathanOn Fri, 17 Mar 2000, Phoenix Kokido wrote:

In my game I’m going to have a multilevel background. So that as you walk
along, the elements of the background scroll at different speeds giving
you that wonderful Super Nintendo-esque Almost 3D look. So, any how I’m
trying to decide how I should do this. Currently I’m reblitting everything
every time anything changes, and this is really killing the frame rate.

Consoles have dedicated multi-layer video hardware to do this. Most computers
don’t (isn’t it a pity).

Try using dirty rectangles to only reblit what has changed. If your
entire background is scrolling (not just fixed objects), you have a no
choice but repainting it all. This alone could be reason for altering the
design of your game.

In my game I’m going to have a multilevel background. So that as you walk
along, the elements of the background scroll at different speeds giving
you that wonderful Super Nintendo-esque Almost 3D look. So, any how I’m
trying to decide how I should do this. Currently I’m reblitting everything
every time anything changes, and this is really killing the frame rate.

I did this when I started working on a new version of BoboBot.

Since lots of action is going to happen, and since scrolling will happen
most of the time, I just redraw the entire screen (which means erasing it
all, then drawing each parallax layer (backgrounds)) every frame.

And yes, it does kill the frame rate. That’s why PC’s need better 2D
video hardware, a la SNES. :wink: (I can’t believe I just said that :wink: )

-bill!

For starters SDL_DisplayFormat should be used after you color key an
image, and I think the SDL_ConvertSurface you have at the end of the
image load does the same thing as SDL_DisplayFormat, so you’d be
better off just sticking it in the end of the function. This is just
being picky.

As for speeding up the game code, it’s those two big blits that are
killing the speed. Since you are going to do paralax scrolling you
will need multiple blits, I suggest making the tree part of the
background multiple tiles to try to cut down on the amount of alpha
you need to blit (alpha blits are slower than normal blits without
hardware assists). Most imporantly don’t blit the background more
than you have to. I saw where you initially only drew it if the
player moved and the bg scrolled. When I uncommented the the ‘if’ I
saw that the blit trailed all over the place, so I threw in a real
quick (and buggy) back ground save routine and the frame rate jumped
up. The way your code is now their is way too much overdraw and big
blits hurt performance. Hope that helps.

Phoenix Kokido
members.xoom.com/kokido
@Wes_Poole

Jonathan Miller wrote:> On Fri, 17 Mar 2000, Phoenix Kokido wrote:

The biggest thing I’ve discovered is to always use SDL_DisplayFormat
on surfaces before you try to blit with them

Yeah, I’m already doing that.

If you are already doing that then you should probably go ahead and
put a tarball up on the web somewhere for some peer review.

Well anyone who’s kind enough to visit:
www.kludge.org/dirty-monkey-0.0.1.tar.bz2
or
www.kludge.org/dirty-monkey-0.0.1.tar.gz

will find a copy of the code. Just type make and pray everything
works.

Thanks again,

– Jonathan

In my game I’m going to have a multilevel background. So that as you walk
along, the elements of the background scroll at different speeds giving
you that wonderful Super Nintendo-esque Almost 3D look. So, any how I’m
trying to decide how I should do this. Currently I’m reblitting everything
every time anything changes, and this is really killing the frame rate.

I did this when I started working on a new version of BoboBot.

Since lots of action is going to happen, and since scrolling will happen
most of the time, I just redraw the entire screen (which means erasing it
all, then drawing each parallax layer (backgrounds)) every frame.
Yeah I had the same problem when I made my animated mouse pointer demo. I
was trying to get rid of the “turds” left on the screen when the mouse was
moved too fast.

I fixed it by updating the screen all at once. Now I cut pieces out which
speeds it up a lot.

DaveOn Fri, 17 Mar 2000, William Kendrick wrote:

And yes, it does kill the frame rate. That’s why PC’s need better 2D
video hardware, a la SNES. :wink: (I can’t believe I just said that :wink: )

-bill!

For starters SDL_DisplayFormat should be used after you color key an
image, and I think the SDL_ConvertSurface you have at the end of the
image load does the same thing as SDL_DisplayFormat, so you’d be
better off just sticking it in the end of the function. This is just
being picky.
RLEACCEL would prolly help with all the transparent blits, though I din’t
notice much increase myself.

As for speeding up the game code, it’s those two big blits that are
killing the speed. Since you are going to do paralax scrolling you
will need multiple blits, I suggest making the tree part of the
background multiple tiles to try to cut down on the amount of alpha
you need to blit (alpha blits are slower than normal blits without
hardware assists). Most imporantly don’t blit the background more
than you have to. I saw where you initially only drew it if the
player moved and the bg scrolled. When I uncommented the the ‘if’ I
saw that the blit trailed all over the place, so I threw in a real
quick (and buggy) back ground save routine and the frame rate jumped
up. The way your code is now their is way too much overdraw and big
blits hurt performance. Hope that helps.
the problem here is that when the SNES did this kinda effect it could
latch onto the horiztonal sync and simply change the background color
every few scanlines, not so anymore unfortunatly. I don’t really know how
this is done this days, just don’t think its possible really:(
As you said, the foreground should definitely be tile based and not one
big image.

Long live the confused,
Akawaka.On Fri, 17 Mar 2000, Phoenix Kokido wrote:

Bother! said Pooh and hid Piglet’s corpse.

Phoenix Kokido wrote …

As for speeding up the game code, it’s those two big
blits that are killing the speed.

Two things can help this and apply to any design,

  1. Use 8-bit graphics
  2. Use SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF

Quick benchmarks, 400Mhz / P2 / Rage LT Pro / Win98 / DirectX 7 …

Slightly Modified “Dirty Little Monkey” Demo

640x480x16, windowed = 11 fps
640x480x8, windowed = 30 fps
640x480x16, full screen, hardware, double buffered = 85 fps
640x480x8, full screen, hardware, double buffered = 85 fps
640x480x16, full screen, hardware = 215 fps
640x480x8, full screen, hardware = 446 fps

Note that directx synced the double buffered page flips to the monitor. The
last two flickered horribly and were only added to check raw throughput. The
main advantage of using 8-bit images in hardware mode is that that you can
store more images as hardware surfaces.

After this, I tried turning off the color key for the base background layer
since it is not needed …

640x480x16, windowed = 25 fps
640x480x8, windowed = 43 fps

The hardware modes came out the same as in the first benchmarks, indicating
that hardware colorkey does not affect performance on my system.

Hope this helps. ( btw, cute title graphics :slight_smile:

  • Randi

Regimental Command
Generic Armored Combat System
http://www-users.cs.umn.edu/~relander/regcom/index.html

The SNES graphics core was designed to do this stuff, it had 3
floating layers over a background in hardware, PC’s just try to throw
this stuff on an existing frame buffer. Decent rates are possible on
a PC though, as I said before my project (glutton) has a tile layer
and an isometric layer floating over it, both are redrawn every frame
and I get about ~16 fps. But all I blit are multiple 64 x 64 tiles
and they all blit pretty quickly, plus my code is really unoptimized.
If I did want to do something and it seemed like I was fighting SDL to
try to get the speed (like multiple floating layers) I would probably
end up go down to the lowest layer of bit twiddling in the display
surface (or a offscreen buffer), use my own alpha code for the layers,
and just update that one surface.

Phoenix Kokido
members.xoom.com/kokido
@Wes_Poole

Martin Donlon wrote:> On Fri, 17 Mar 2000, Phoenix Kokido wrote:

For starters SDL_DisplayFormat should be used after you color key an
image, and I think the SDL_ConvertSurface you have at the end of the
image load does the same thing as SDL_DisplayFormat, so you’d be
better off just sticking it in the end of the function. This is just
being picky.
RLEACCEL would prolly help with all the transparent blits, though I din’t
notice much increase myself.

As for speeding up the game code, it’s those two big blits that are
killing the speed. Since you are going to do paralax scrolling you
will need multiple blits, I suggest making the tree part of the
background multiple tiles to try to cut down on the amount of alpha
you need to blit (alpha blits are slower than normal blits without
hardware assists). Most imporantly don’t blit the background more
than you have to. I saw where you initially only drew it if the
player moved and the bg scrolled. When I uncommented the the ‘if’ I
saw that the blit trailed all over the place, so I threw in a real
quick (and buggy) back ground save routine and the frame rate jumped
up. The way your code is now their is way too much overdraw and big
blits hurt performance. Hope that helps.
the problem here is that when the SNES did this kinda effect it could
latch onto the horiztonal sync and simply change the background color
every few scanlines, not so anymore unfortunatly. I don’t really know how
this is done this days, just don’t think its possible really:(
As you said, the foreground should definitely be tile based and not one
big image.

Long live the confused,
Akawaka.

Bother! said Pooh and hid Piglet’s corpse.

Just thought I would add that 8 bit is significantly faster in linux
too. Some people like 16 bit color though, but it would probably work
well for this type of game.

Phoenix Kokido
members.xoom.com/kokido
@Wes_Poole

Randi J. Relander wrote:

Phoenix Kokido wrote …

As for speeding up the game code, it’s those two big
blits that are killing the speed.

Two things can help this and apply to any design,

  1. Use 8-bit graphics
  2. Use SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF

Quick benchmarks, 400Mhz / P2 / Rage LT Pro / Win98 / DirectX 7 …

Slightly Modified “Dirty Little Monkey” Demo

640x480x16, windowed = 11 fps
640x480x8, windowed = 30 fps
640x480x16, full screen, hardware, double buffered = 85 fps
640x480x8, full screen, hardware, double buffered = 85 fps
640x480x16, full screen, hardware = 215 fps
640x480x8, full screen, hardware = 446 fps

Note that directx synced the double buffered page flips to the monitor. The
last two flickered horribly and were only added to check raw throughput.
The> main advantage of using 8-bit images in hardware mode is that that you can
store more images as hardware surfaces.

After this, I tried turning off the color key for the base background layer
since it is not needed …

640x480x16, windowed = 25 fps
640x480x8, windowed = 43 fps

The hardware modes came out the same as in the first benchmarks, indicating
that hardware colorkey does not affect performance on my system.

Hope this helps. ( btw, cute title graphics :slight_smile:

  • Randi

Regimental Command
Generic Armored Combat System
http://www-users.cs.umn.edu/~relander/regcom/index.html

If I did want to do something and it seemed like I was fighting SDL to
try to get the speed (like multiple floating layers) I would probably
end up go down to the lowest layer of bit twiddling in the display

Oh - it might be nice to have an API in SDL where you could blit to
multiple surfaces (for Heads-Up Displays, Parallax scrolling, etc.)
and SDL would handle mixing them together into one surface.

In the future if video hardware actually ever supports this, it would be
easy to implement. :wink:

Just a thot.

-bill!

Oh - it might be nice to have an API in SDL where you could blit to
multiple surfaces (for Heads-Up Displays, Parallax scrolling, etc.)
and SDL would handle mixing them together into one surface.

I second that, although I’m not sure if it’s not beyond SDLs scope.
But blitting several surfaces over each other might be faster if you know
beforehand that you want to do it. I a blitter accounts for this it need not
read and write out pixels that will be covered later anyway. On the other
hand simultaneously reading from multiple surfaces might be bad for caches
or read-ahead-buffers or whatnot. I tried this once (on the ARM) and I think
it was cool (at least in 32bit-depth). It could look like this:

SDL_MultiBlit (int NumberOfSurfaces, SDL_Surface **src, SDL_Rect **srcrect,
SDL_Surface *dst, SDL_Rect *dstrect)

And work, in it’s simples form, like this (pseudocode):

for (y…) {
for (x…) {
for (surface = top; surface < bottom; surface = next_lower_surface {
// the first opaque pixel gets written, and the loop for this pixel
// is quit, going on to the next coordinate
if (surface(x,y) = opaque) {
write_pixel(surface(x,y);
next;
}
}
}
}

That would probalby only be good for very complex scenes, because it can’t
easily make use of RLE-encoding and memcpy-thingies. (But perhaps not-so-
easily)

In the future if video hardware actually ever supports this, it would be
easy to implement. :wink:

I’m always shocked when I realize how much cpu-time is sucked away by simple
scrolling, something which took like 6 cycles for a poke to 53270 on a C=64.
PCs are so often used as unsophisticated brute-force machines, but even
500MHz CPUs stand no chance against years old special-(console-)hardware.
Do todays graphics-boards realy not support such things like parallax-
scrolling, sprites etc, or is it just that there is no standard ?
Or does nobody want such features any more, in the age of 3D-ego-shooters ?

So, in the absence of HW-accelerated support, I think a multi-surface-blit-
function could be faster and therefore good, perhaps as part of hermes, I
don’t know where it would fit best.

All the best,
robOn Fri, Mar 17, 2000 at 05:45:49PM -0800, William Kendrick wrote:

“Randi J. Relander” wrote:

  1. Use 8-bit graphics

I disagree here. It only is faster if the screen resolution is 8 bit
too. Also note that if the screen resolution really is 8 bit you will
limit yourself to 256 colors - like those good old DOS times. So my
suggestion is use 16 bit graphics - or at least either set the videomode
to 16 bpp with SDL or pass 0 as the bit depth. So you could still use 8
bit graphics whereof the opposite doesn’t work. Also always convert your
image data to the screen resolution when you load the images. This
avoids conversion (big performance gain).

16 bit is the fastest true color mode and 24 bit is the slowest. 32 is
somewhere in the middle usually closer to 32 bit. Blitting 8 bit
graphics to a true color mode suffers from a table lookup for each
blitted pixel and is a big speed penalty (this can be avoided by a
conversion once (SDL can do it for you)).

On Linux without DGA 2.0 there is no good possibility (starting a second
X Server e.g. is an ugly hack) to switch resolutions and most users
will run in 16 bit color depth so you will gain nothing using 8 bit
graphics (they are not even smaller if you use compression).

Besides the raw blitting speed on Windows is immense so you don’t have
to worry about the costs of a blit there. With Linux it is not that good
but it still is fast enough for most purposes - and XFree 4.0 boosts
that so you really should use 16 bit graphics :)–
Daniel Vogel My opinions may have changed,
666 @ http://grafzahl.de but not the fact that I am right

Oh - it might be nice to have an API in SDL where you could blit to
multiple surfaces (for Heads-Up Displays, Parallax scrolling, etc.)
and SDL would handle mixing them together into one surface.

Yes! And we’ll convince Loki to port some gorgeous Japanese Shmups!
Oooooh, the joy…

In the future if video hardware actually ever supports this, it would be
easy to implement. :wink:

It is already supported by some hardware. In fact, X11 allows it, and
workstations have had transparent overlay visuals for years, so it is just
a matter of waiting for the PC world to catch up. XFree86 4.0 supports
overlay visuals on some boards, but I don’t know if they support
transparency yet. (Can anyone with a capable video board/X server test
this?)

There is another trick that I’d like to add SDL support for:
For games with a soft scrolling background, it is useful to have a back
buffer that is somewhat bigger than the output window/screen. That way you
can keep a larger part of the playfield drawn, and only have to repaint it
occasionally, shifting the buffer in large (say, tile sized) steps.

This is a big win on X11 and MIT-SHM, and less (if at all) when drawing is
done directly on the hardware. I’m using it in a game (non-SDL right now)
since I want portable performance. I’m thinking of a suitable SDL API
for it.

I disagree here. It only is faster if the screen resolution is 8 bit
too. Also note that if the screen resolution really is 8 bit you wil

While it is always good to have screen and graphics formats the same (this
is what DisplayFormat solves for you), copying 16bit images around is
basically copying twice as much data than copying 8bit images round.

It does depend on your current display depth, whether you use
DisplayFormat, as well as your image depth.–
Brian

This is a big win on X11 and MIT-SHM, and less (if at all) when drawing is
done directly on the hardware. I’m using it in a game (non-SDL right now)
since I want portable performance. I’m thinking of a suitable SDL API
for it.

Please do. I’m very interested in adding this if there is hardware
acceleration support on some platforms. It will be very useful for
Pirates Ho! :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

This is a big win on X11 and MIT-SHM, and less (if at all) when drawing
is

done directly on the hardware. I’m using it in a game (non-SDL right now)
since I want portable performance. I’m thinking of a suitable SDL API
for it.

Please do. I’m very interested in adding this if there is hardware
acceleration support on some platforms. It will be very useful for
Pirates Ho! :slight_smile:

On a side note, what sort of engine are you planning on using for Pirates
Ho!? I have a few interesting ideas about water reflection in 2D
environments that I’ve been meaning to try out… :wink:

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

Nicholas

Nicholas Vining “While you’re out there struggling
vining at pacificcoast.net with your computer, I’m naked,
icq: 20872003 clueless, and feeling good!”
- Ratbert

----- Original Message -----
From: slouken@devolution.com (Sam Lantinga)
To: sdl at lokigames.com
Date: Friday, March 17, 2000 9:29 PM
Subject: Re: [SDL] Optimization

Or does nobody want such features any more, in the age of 3D-ego-shooters ?

Mouse pointers and pulldown menus and even just plain old windowing
systems in general could really be helped by sprites and multiple layers of
plain blitting. :slight_smile:

-bill!