"buffering" Tile-based surface to avoid loop on draw phase

Hello everyone, i have a newbie question.

I am doing basic animation as seen in any SDL tutorial over there, however there is something that isn’t working:

when reading game resources, i load the background resource and the scenario map, and then, still in the init() phase, i try to fill a SDL_surface with the resulting background, so i avoid the big loop on draw.

the problem is i don’t have it working properly.

for instance, if i move the very same loop from init phase to draw phase, it works perfectly, but in this way the draw becomes slower.

is there possible to render entire background before animation starts so i avoid to recreate it again and again?

thanks in advance.

btw, here goes the actual relevant code:

Code:

/*

*/

#include “Scenario.hh”

Scenario::Scenario(json_object json_scenario) {
json_object json = json_object_object_get(json_scenario, “scenario_name”);
name = (char
) json_object_get_string(json);
json = json_object_object_get(json_scenario, “resource”);
char
res = (char*) json_object_get_string(json);
json = json_object_object_get(json_scenario, “tile_width”);
tileWidth = json_object_get_int(json);
json = json_object_object_get(json_scenario, “tile_height”);
tileHeight = json_object_get_int(json);
json = json_object_object_get(json_scenario, “rows”);
rows = json_object_get_int(json);
json = json_object_object_get(json_scenario, “cols”);
cols = json_object_get_int(json);
resource = IMG_Load(res);
buffer = SDL_CreateRGBSurface(SDL_HWSURFACE, //
rows * tileWidth, rows * tileHeight, 32, 0, 0, 0, 0);
SDL_Rect a;
SDL_Rect b;
a.x = b.x = 0;
a.y = b.y = 0;
a.w = b.w = tileWidth;
a.h = b.h = tileHeight;
int i = -1;
while (++i < rows) {
int j = -1;
while (++j < cols) {
b.x = tileWidth * i;
b.y = tileHeight * j;
SDL_BlitSurface(resource, &a, buffer, &b);
}
}
pos.x = des.x = 0;
pos.y = des.y = 0;
pos.w = des.w = tileWidth;
pos.h = des.h = tileHeight;
}

void Scenario::step(int delta, SDL_Event event) {

}

void Scenario::draw(SDL_Surface* screen) {
// SDL_Rect a;
// SDL_Rect b;
// a.x = b.x = 0;
// a.y = b.y = 0;
// a.w = b.w = tileWidth;
// a.h = b.h = tileHeight;
// int i = -1;
// while (++i < 100) {
// int j = -1;
// while (++j < 100) {
// b.x = tileWidth * i;
// b.y = tileHeight * j;
// SDL_BlitSurface(resource, &a, screen, &b);
// }
// }
SDL_BlitSurface(buffer, &des, screen, &pos);
}

for context the entire code can be seen there:
http://code.google.com/p/sombriks-hq/source/browse/#svn%2Ftrunk%2Fsdl-sample

I notice you’re not converting your image after you’ve loaded it with IMG_Load. This means that every time you blit your image, SDL has to convert it, which will cause a performance hit. After you’ve loaded up your image, call SDL_DisplayFormat to do a one time conversion.

Code:
SDL_Surface *loadImage(char name)
{
/
Load the image using SDL Image */

SDL_Surface *temp;
SDL_Surface *image;

temp = IMG_Load(name);

if (temp == NULL)
{
	printf("Failed to load image %s", name);
	
	exit(1);
}

/* Convert the image to the screen's native format */

image = SDL_DisplayFormat(temp);

SDL_FreeSurface(temp);

if (image == NULL)
{
	printf("Failed to convert image %s to native format", name);
	
	exit(1);
}

/* Return the processed image */

return image;

}------------------------
The Legend of Edgar. A 2D platformer for Windows and Linux. (http://www.parallelrealities.co.uk/p/legend-of-edgar.html)

Hello everyone, thanks for the answers.

Indeed i’ll convert the image, my mistake.

also the buffer strategy works, the problem was this:

Code:

pos.x = des.x = 0;
pos.y = des.y = 0;
pos.w = des.w = tileWidth;
pos.h = des.h = tileHeight;

i changed to this:

Code:

pos.x = des.x = 0;
pos.y = des.y = 0;
pos.w = des.w = tileWidth * cols;
pos.h = des.h = tileHeight * rows;

special thanks to Carl Lefran?ois for pointing that now obvious mistake.

omg, I looked at my own games and found that I had failed to convert in
many places. You helped me too :slight_smile: thanxOn Mon, Mar 12, 2012 at 5:39 AM, riksweeney wrote:

**
I notice you’re not converting your image after you’ve loaded it with
IMG_Load. This means that every time you blit your image, SDL has to
convert it, which will cause a performance hit. After you’ve loaded up your
image, call SDL_DisplayFormat to do a one time conversion.

Code:

SDL_Surface *loadImage(char name)
{
/
Load the image using SDL Image */

SDL_Surface *temp;
SDL_Surface *image;

temp = IMG_Load(name);

if (temp == NULL)
{
printf(“Failed to load image %s”, name);

  exit(1);

}

/* Convert the image to the screen’s native format */

image = SDL_DisplayFormat(temp);

SDL_FreeSurface(temp);

if (image == NULL)
{
printf(“Failed to convert image %s to native format”, name);

  exit(1);

}

/* Return the processed image */

return image;
}


The Legend of Edgar. A 2D platformer for Windows and Linux.http://www.parallelrealities.co.uk/p/legend-of-edgar.html


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org