Learner's trouble with framerate drop

Hi,

I’m trying to knock up a very simple game for my own amusement and have run into difficulties.

Initially I drew a simple ball on the screen and movred it left and right by holding down the relevant mouse button. This produced a frame-rate of apx. 70 fps : so far so good !

Next I drew another simple sprite and implemented no movement for that. The ball movement became very sluggish - the fram rate had dropped to apx 37 fps.

I wasn’t sure what was going on here so I guessed. Both images were BMPs with a colour-depth of 16 out of 16 million colours. Thinking this could be slowing things down but not really believing it (:])I dropped the pixel depth to 8/256 colours and tried again. Frame rate was still 37fps but this time the Colour Key was no longer transparent :frowning:

What probably is transparent is that I’m a total novice at this and really do not know where to look next. If anyone can give me some pointers as to what may be causing these problems I’d be obliged.

I set the video mode to 1024 x 768 x 8 and the videoflags to :

SDL_HWSURFACE | SDL_FULLSCREEN | SDL_ANYFORMAT | SDL_DOUBLEBUF | SDL_HWPALETTE

No conversion is performed on the images because they are both at 8bpp and nothing much
else happens other than reading the mouse, applying the new velocities wiping the screen
and reblitting the sprites with SDL_BlitSurface then flipping the screens.

I have used the testsprite.c example as a refernce

and cannot spot anything fundamentally different between the two other than the icon.bmp in the image has a colour-depth of 4bpp. When I plugged this image into my app. the frame rate remained at 37 fps. My card is an admittedly old Creative Voodoo Banshee but I would’nt expect this sort of and the demos all seem to perform fine.

I have a hunch that it is my lack of knowledge on what is actually happening with the hardware that’s causing the problems but I have no hunch at all as to where to start looking first.

Any suggestions gratefully received!

Thanks , Kev.–
Kev Grindley
<@Kev_Grindley>

I’m trying to knock up a very simple game for my own amusement and
have run into difficulties.

Initially I drew a simple ball on the screen and movred it left and
right by holding down the relevant mouse button. This produced a
frame-rate of apx. 70 fps : so far so good !

Next I drew another simple sprite and implemented no movement for
that. The ball movement became very sluggish - the fram rate had
dropped to apx 37 fps.

I would say to make sure you’re only calling SDL_UpdateRects() once per
frame, but you say later that you’re using double buffering; seems a bit
strange the framerate would drop so dramatically. Care to show us the
code where you draw each frame?

I set the video mode to 1024 x 768 x 8 and the videoflags to :

SDL_HWSURFACE | SDL_FULLSCREEN | SDL_ANYFORMAT | SDL_DOUBLEBUF |
SDL_HWPALETTE

What format is your display in, and what platform are you using? Do you
check what video mode you are actually getting after initialising it?

If you have a 32bit desktop, it’s quite likely you’ll get a 32bit
display - but it depends on the platform. DirectX on Win32 will probably
give you what you ask for, but X11 probably won’t.

No conversion is performed on the images because they are both at 8bpp
and nothing much else happens other than reading the mouse, applying
the new velocities wiping the screen and reblitting the sprites with
SDL_BlitSurface then flipping the screens.

Always use SDL_DisplayFormat() on every surface you load. In fact, you
might want to write your own loader function:

SDL_Surface *load_image (const char *filename)
{
SDL_Surface *temp, *newsfc;

temp = IMG_Load (filename);
if (temp == NULL)
	return NULL;
newsfc = SDL_DisplayFormat (temp);
SDL_FreeSurface (temp);

return newsfc;

}

I have a hunch that it is my lack of knowledge on what is actually
happening with the hardware that’s causing the problems but I have no
hunch at all as to where to start looking first.

Post some code if you can’t work it out; if your demo’s really small
post the whole thing, otherwise just the main loop and blitting code.

Also check what video mode you’re actually getting, it might be not what
you expect. Some sample code, where ‘screen’ is the result of
SDL_SetVideoMode(), or just SDL_Surface *screen = SDL_GetVideoSurface();

fprintf (stdout, “Screen format: %dx%dx%lubpp [flags=%lx”
"(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)]",
screen->w, screen->h,
screen->format->BitsPerPixel,
screen->flags,
(screen->flags & SDL_HWSURFACE ? “HW” : “SW”),
(screen->flags & SDL_ASYNCBLIT ? “AsyncBlit” : “SyncBlit”),
(screen->flags & SDL_ANYFORMAT ? “AnyFmt” : “OneFmt”),
(screen->flags & SDL_HWPALETTE ? “HwPalette” : “SwPalette”),
(screen->flags & SDL_DOUBLEBUF ? “DblBuf” : “NoDblBuf”),
(screen->flags & SDL_FULLSCREEN ? “Fullscreen” : “Windowed”),
(screen->flags & SDL_HWACCEL ? “HwAccelBlits” : “UnaclBlit”),
(screen->flags & SDL_RLEACCEL ? “RLEaccel” : “NoRLEaccel”),
(screen->flags & SDL_SRCALPHA ? “Alpha” : “NoAlpha”),
(screen->flags & SDL_PREALLOC ? “PreAlloc” : “NoPreAlloc”)
);

Anyway, good luck. One final thing to note is that 2D graphics hardware
basically sucks, and pushing 1024x768 at 8bit = 780kb to the video card
for every frame; so at 37fps you’re pushing 29mb per second. Have you
tried lower resolutions to see if they’re significantly faster?

For example, my little game runs at about 50fps in 640x480; at 800x600
it falls to about 35fps. This is under X on a 400mhz system with, yep, a
3Dfx Banshee, in 16bit.

A vaguely interesting tidbit:

mike at satan:~$ echo $[1024 * 768 * 1 * 37]
29097984
mike at satan:~$ echo $[640 * 480 * 2 * 50]
30720000On Mon, Feb 25, 2002 at 07:12:37PM +0000, Kev Grindley wrote:

Mike.
You read it, you can’t unread it.
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20020225/e0818c02/attachment.pgp

Oh? One should do this? /me finds this odd. I’ve never done this in the SDL
program i’m working on and never had a problem, err…why exactly should one do
this?

-EvilTypeGuy> On Mon, Feb 25, 2002 at 07:12:37PM +0000, Kev Grindley wrote:

Always use SDL_DisplayFormat() on every surface you load. In fact, you
might want to write your own loader function:

SDL_Surface *load_image (const char *filename)
{
SDL_Surface *temp, *newsfc;

temp = IMG_Load (filename);
if (temp == NULL)
return NULL;
newsfc = SDL_DisplayFormat (temp);
SDL_FreeSurface (temp);

return newsfc;
}

Always use SDL_DisplayFormat() on every surface you load. In fact, you
might want to write your own loader function:

Oh? One should do this? /me finds this odd. I’ve never done this in the SDL
program i’m working on and never had a problem, err…why exactly should one do
this?

If you’re image surface is in 32bit, but the screen was only able to
open in 16bit, for example, then EVERY time you blit, it will need
to convert. This == SLOW.

If you convert ONCE, the blits will be fast.

-bill!On Mon, Feb 25, 2002 at 05:35:30PM -0600, EvilTypeGuy wrote:

On Mon, Feb 25, 2002 at 07:12:37PM +0000, Kev Grindley wrote:

Always use SDL_DisplayFormat() on every surface you load. In fact,
you
might want to write your own loader function:

SDL_Surface *load_image (const char *filename)
{
SDL_Surface *temp, *newsfc;

temp = IMG_Load (filename);
if (temp == NULL)
return NULL;
newsfc = SDL_DisplayFormat (temp);
SDL_FreeSurface (temp);

return newsfc;
}

Oh? One should do this? /me finds this odd. I’ve never done this in the
SDL
program i’m working on and never had a problem, err…why exactly
should one do
this?

yep you should see dramatic speed improvement. i did.On Monday, February 25, 2002, at 05:35 PM, EvilTypeGuy wrote:

On Mon, Feb 25, 2002 at 07:12:37PM +0000, Kev Grindley wrote:

-EvilTypeGuy


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Thanks Mike (and everyone) for making some suggestions for me to persue.
Basically, about 15 minutes after I posted my questions I sussed the slow frame rate. Sod’s Law ! It was really silly error in that I was calling a generic ‘draw_sprite()’ function within the game loop twice : the trouble was this procedure contained the SDL_Flip() call, too, which meant I was doing two screen flips per frame. Not good for performance really. Doh! Anyway, I removed it and the frame returnd to apx 75 fps.

Apologies I forgto the important stuff like I was working on a 32 bit display in WinME. The other problem regarding the Color Key not being transparent still happens if I try and use 8bpp sprites on an 8bpp screen.

Not sure why this happens so any pointers on this one would be gratefully received (again). I didn’t call SDL_DisplayFormat() in the 8bits on 8bits scenario because I resoned I didn’t need to. I left this call in early on in the expriment by mistake and it cause segmentation fault.

So, currently the only way I can display my sprites is by using non 8-bit images on an 8-bit screen and calling SDL_DisplayFormat(). So, I guess I’m missing something else in the puzzle and will have to trawl GameDev or something to get some more graphics nous.

As I say any suggestions re the ColorKey issue and I’d be grateful, but thanks in the meantime !

Kev> On Mon, Feb 25, 2002 at 07:12:37PM +0000, Kev Grindley wrote:

I’m trying to knock up a very simple game for my own amusement and
have run into difficulties.

Initially I drew a simple ball on the screen and movred it left and
right by holding down the relevant mouse button. This produced a
frame-rate of apx. 70 fps : so far so good !

Next I drew another simple sprite and implemented no movement for
that. The ball movement became very sluggish - the fram rate had
dropped to apx 37 fps.

I would say to make sure you’re only calling SDL_UpdateRects() once per
frame, but you say later that you’re using double buffering; seems a bit
strange the framerate would drop so dramatically. Care to show us the
code where you draw each frame?

I set the video mode to 1024 x 768 x 8 and the videoflags to :

SDL_HWSURFACE | SDL_FULLSCREEN | SDL_ANYFORMAT | SDL_DOUBLEBUF |
SDL_HWPALETTE

What format is your display in, and what platform are you using? Do you
check what video mode you are actually getting after initialising it?

If you have a 32bit desktop, it’s quite likely you’ll get a 32bit
display - but it depends on the platform. DirectX on Win32 will probably
give you what you ask for, but X11 probably won’t.

No conversion is performed on the images because they are both at 8bpp
and nothing much else happens other than reading the mouse, applying
the new velocities wiping the screen and reblitting the sprites with
SDL_BlitSurface then flipping the screens.

Always use SDL_DisplayFormat() on every surface you load. In fact, you
might want to write your own loader function:

SDL_Surface *load_image (const char *filename)
{
SDL_Surface *temp, *newsfc;

temp = IMG_Load (filename);
if (temp == NULL)
return NULL;
newsfc = SDL_DisplayFormat (temp);
SDL_FreeSurface (temp);

return newsfc;
}

I have a hunch that it is my lack of knowledge on what is actually
happening with the hardware that’s causing the problems but I have no
hunch at all as to where to start looking first.

Post some code if you can’t work it out; if your demo’s really small
post the whole thing, otherwise just the main loop and blitting code.

Also check what video mode you’re actually getting, it might be not what
you expect. Some sample code, where ‘screen’ is the result of
SDL_SetVideoMode(), or just SDL_Surface *screen = SDL_GetVideoSurface();

fprintf (stdout, “Screen format: %dx%dx%lubpp [flags=%lx”
"(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)]",
screen->w, screen->h,
screen->format->BitsPerPixel,
screen->flags,
(screen->flags & SDL_HWSURFACE ? “HW” : “SW”),
(screen->flags & SDL_ASYNCBLIT ? “AsyncBlit” : “SyncBlit”),
(screen->flags & SDL_ANYFORMAT ? “AnyFmt” : “OneFmt”),
(screen->flags & SDL_HWPALETTE ? “HwPalette” : “SwPalette”),
(screen->flags & SDL_DOUBLEBUF ? “DblBuf” : “NoDblBuf”),
(screen->flags & SDL_FULLSCREEN ? “Fullscreen” : “Windowed”),
(screen->flags & SDL_HWACCEL ? “HwAccelBlits” : “UnaclBlit”),
(screen->flags & SDL_RLEACCEL ? “RLEaccel” : “NoRLEaccel”),
(screen->flags & SDL_SRCALPHA ? “Alpha” : “NoAlpha”),
(screen->flags & SDL_PREALLOC ? “PreAlloc” : “NoPreAlloc”)
);

Anyway, good luck. One final thing to note is that 2D graphics hardware
basically sucks, and pushing 1024x768 at 8bit = 780kb to the video card
for every frame; so at 37fps you’re pushing 29mb per second. Have you
tried lower resolutions to see if they’re significantly faster?

For example, my little game runs at about 50fps in 640x480; at 800x600
it falls to about 35fps. This is under X on a 400mhz system with, yep, a
3Dfx Banshee, in 16bit.

A vaguely interesting tidbit:

mike at satan:~$ echo $[1024 * 768 * 1 * 37]
29097984
mike at satan:~$ echo $[640 * 480 * 2 * 50]
30720000

Mike.
You read it, you can’t unread it.


Kev Grindley
<@Kev_Grindley>