Hello everybody,
I'm really making good progress with one of my applications at the moment, I have written a basic GUI for it and it works fine and I have isometric tiles on several layers included. It all works, but it's slow - this leads me to the question:
I draw 20x20 simple bitmap tiles to the screen every frame. Each tile has a width of 18 and a height of 9, but that shouldn't matter. It looks like this:
Ignore the GUI and the (two) cursors for now, they are not the problem, I tested that.
When I run the program at 640x480 for example in windowed mode, it's fast, but when I run it in fullscreen, it really drops the framerate to around 2-6 fps. The problem are the tiles, so I guess I'll show you how I draw my tiles and how I set up my window:
The init- and draw-function for my tiles, those are called in loops for every tile...
void ctile::init ( SDL_Surface* screen_surface, int _x, int _y, TILE_TYPE _type )
// initializes the tile
{
// initialize the sprite
switch ( _type )
{
case tile_grass:
sprite.init ( screen_surface, "tiles/grass.bmp" );
break;
case tile_concrete:
sprite.init ( screen_surface, "tiles/concrete.bmp" );
break;
case tile_dirt:
sprite.init ( screen_surface, "tiles/dirt.bmp" );
break;
case tile_grass_ramp_x:
sprite.init ( screen_surface, "tiles/grass_ramp_x.bmp" );
break;
case tile_grass_ramp_y:
sprite.init ( screen_surface, "tiles/grass_ramp_y.bmp" );
break;
case tile_grass_ramp_xy:
sprite.init ( screen_surface, "tiles/grass_ramp_xy.bmp" );
break;
case tile_rail_y:
sprite.init ( screen_surface, "tiles/rail_y.bmp" );
break;
default:
break;
}
// position the tile
sprite.x = ( float ) _x;
sprite.y = ( float ) _y;
// save position
x = _x;
y = _y;
// save type
type = _type;
}
void ctile::draw ( void )
// draws the tile
{
if ( type != tile_empty )
// if the tile is not empty
// draw the sprite
sprite.draw ( x, y );
}
And now you'll also need to see the sprite-drawing functions I use, I guess, so here we go:
void csprite::init ( SDL_Surface* screen_surface, const char *filename, int _width, int _height )
// initializes the sprite
{
// load the bitmap
bitmap = SDL_LoadBMP ( filename );
// set the sprites surface to screen_surface
surface = screen_surface;
if ( bitmap == NULL )
// if there was an error
return_error ( "Failed to initialize sprite..." );
// set up other variables
width = _width;
height = _height;
}
void csprite::draw ( )
// draws the sprite to the screen
{
// create a source rectangle
SDL_Rect source;
source.x = 0;
source.y = 0;
source.w = bitmap->w;
source.h = bitmap->h;
// create a destination rectangle
SDL_Rect destination;
destination.x = ( int ) x;
destination.y = ( int ) y;
destination.w = width;
destination.h = height;
// activate color keying
/*if ( !*/SDL_SetColorKey ( bitmap, SDL_SRCCOLORKEY, SDL_MapRGB ( bitmap->format, 255, 0, 128 ) ); //)
// if there was an error
//return_error ( "Failed to colorkey sprite..." );
// blit the bitmap to the screen
/*if ( !*/SDL_BlitSurface ( bitmap, &source, surface, &destination );// )
// if there was an error
//return_error ( "Failed to draw sprite..." );
}
void csprite::draw ( float _x, float _y )
// draws the sprite to the screen at a given location
{
// position the sprite
x = _x;
y = _y;
// draw it
draw ( );
}
And now how I set up my window:
void cwindow::create ( const char* title, const char* filename )
// creates the window
{
// load the settings
load_settings ( filename );
// initialize systems
SDL_Init ( SDL_INIT_VIDEO );
atexit ( SDL_Quit );
if ( fullscreen )
// if we want a fullscreen window
// create a fullscreen window
surface = SDL_SetVideoMode ( width, height, bpp, SDL_SWSURFACE | SDL_ANYFORMAT | SDL_FULLSCREEN );
if ( !fullscreen )
// if we don't want a fullscreen window
// create a windowed window
surface = SDL_SetVideoMode ( width, height, bpp, SDL_SWSURFACE | SDL_ANYFORMAT );
if ( surface == NULL )
// if there was an error
return_error ( "Failed to create window..." );
// set window title
SDL_WM_SetCaption ( title, NULL );
// store screen dimensions
screen_width = width;
screen_height = height;
// hide standard mouse cursor
//SDL_ShowCursor ( SDL_DISABLE );
}
void cwindow::clear ( void )
// clears the window
{
// clear the window
SDL_FillRect ( surface, NULL, 0 );
}
void cwindow::update ( void )
// updates the window
{
// update the window
SDL_Flip ( surface );
}
In my main-function, I call window.clear every frame first, then draw everything, then window.update...
Has anybody got a clue what might be wrong here? I really hate having my program work only in windowed mode or extremely slow, so I'd appreciate any help.
Thanks ahead of time.
[Edited by - d h k on April 23, 2007 7:04:52 AM]