Sign in to follow this  
skwee

Cant store SDL_Surface* at std::vector :\

Recommended Posts

skwee    337
Hello. I created a vector: #define MAXTILES 3 typedef std::vector<SDL_Surface*> Tileset; then i tried to load some picture into my vector: Tileset tileset(MAXTILES); int i; char str[32]; for(i = 0; i < MAXTILES; i++) { memset(str, '\0', 32); sprintf(str, "graphics/texture%d.png", i); tileset.push_back(IMG_Load(str)); } And when I'm trying to Blit some of these picture i get a black screen, nothing :something like SDL_BlitSurface(tilset[0/1/2], NULL, screen, &offset); I Tried also SDL_BlitSurface(tilset.at(0/1/2), NULL, screen, &offset); Am i doing something wrong? BTW its my first experience with vectors.

Share this post


Link to post
Share on other sites
skwee    337
Ok i tried and nothing, the same black screen.
I also tried to write
std::cerr<<tileset[0/1/2]
and at my stderr.txt
i got
000
I mean some why this block of code
int i;
char str[32];
for(i = 0; i < MAXTILES; i++)
{
memset(str, '\0', 32);
sprintf(str, "graphics/texture%d.png", i);
tileset.push_back(IMG_Load(str));
}
dont work correct :\

Share this post


Link to post
Share on other sites
Kylotan    9983
Check the results of IMG_Load, don't just assume it works.

You've also not specified how you got the 'screen' value, or what you're doing to the screen after you've done the blit. (Hint: you typically need to call SDL_Flip().)

Share this post


Link to post
Share on other sites
skwee    337
Few updates:
this is screen
SDL_Surface *screen = NULL;

this is blitting
SDL_BlitSurface(tileset[0], NULL, screen, NULL);
SDL_Flip(screen);

i realized that IMG_Load return null/0 so i tried to copy the error to stderr.txt
std::cerr<<"IMG_Load() error: "<<IMG_GetError();

this is how my stderr.txt looks now:
IMG_Load() error: IMG_Load() error: IMG_Load() error:

No error i cant understand what is wrong?!

Here is the full source of the project:

#define MAXTILES 3
typedef std::vector<SDL_Surface*> Tileset;
SDL_Surface *screen = NULL;

void LoadTiles(Tileset tileset);
void UnloadTiles(Tileset tileset);

int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(WSCREEN, HSCREEN, BPP, SDL_SWSURFACE);
Tileset tileset(MAXTILES);
LoadTiles(tileset);
SDL_BlitSurface(tileset[0], NULL, screen, NULL);
SDL_Flip(screen);
SDL_Delay(1000);
UnloadTiles(tileset);
SDL_Quit();
return 0;
}

void LoadTiles(Tileset tileset)
{
int i;
char str[32];
for(i = 0; i < MAXTILES; i++)
{
memset(str, '\0', 32);
sprintf(str, "graphics/texture%d.png", i);
tileset.push_back(IMG_Load(str));
}
}

void UnloadTiles(Tileset tileset)
{
for(Tileset::size_type i = 0; i < tileset.size(); i++)
SDL_FreeSurface(tileset.at(i));
tileset.clear();
}


One more update:
I also tried to convert the png's to bmp's and load them using SDL_LoadBMP() nothing the same;

[Edited by - Minios on March 5, 2007 11:55:27 AM]

Share this post


Link to post
Share on other sites
Agony    3452
Instead of saying
tileset.push_back(IMG_Load(str));

you should use
tileset[i] = IMG_Load(str);

Notice that when you create the tileset vector, you specify MAXTILES as the size. That means that those elements already exist. When you call .push_back(), it increases the size even further, but leaves those origial MAXTILES elements the way they are (uninitialized).

Share this post


Link to post
Share on other sites
Agony    3452
When you pass the tileset variable into your functions, you pass it by value, which means a copy is made, and the function can read from and write to the copy only. The original doesn't get changed.

So when you load the images into the tileset vector, they only get loaded into the copy. When the program flow returns to the main function, the copy gets destroyed, and the original is still empty. (Well, not empty, but it is uninitialized.)

To fix this, you can pass the tileset vector by reference, which means that instead of making a copy, the function receives a reference to the original. Thus any changes made to the tileset vector inside the function will also effect the original. (And any changes to the original will be visible inside the function, although this doesn't matter in this particular case.)

To do this, add an ampersand (&) after the type name, in the parameter list of the function.

//At the top where you forward-declare your functions:

void LoadTiles(Tileset& tileset);

void UnloadTiles(Tileset& tileset);

//And below where you define them:

void LoadTiles(Tileset& tileset)
{
//...
}

void UnloadTiles(Tileset& tileset)
{
//...
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this