Sign in to follow this  

SDL Surface Problem

This topic is 4303 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone, I've a really weird problem thats driving me crazy, I just cant see whats wrong at all. Basically, I have a texture loader class, which keeps a reference count of how many sprites are using each texture. When a sprite is created, it passes a filename to this class. If that file has already been loaded, then the texture manager just passes back a pointer to the sprite, otherwise it loads the file, and passes back a pointer (when I say pointer, I mean SDL_Surface* by the way). My problem is that somewhere between loading a file, and passing the pointer back to my sprite, the image gets corrupted, and wont draw correctly, or at all. I'm going to post some code, hope it isnt too long, it should be easy to understand though (I hope). Ok, firstly, this class holds the data for each texture that is stored in my resource manager class. The resource manager keeps a std::vector of these Texture objects (ResourceManager::textures).
// texture data object
class Texture
{
public:

	int references;			// reference count
	string filename;		// textures filename
	SDL_Surface* image;		// texture surface

	// constructor
	Texture()
	{
		references = 0;
		image = NULL;
	}

	// destructor
	~Texture()
	{
		if(image)
            SDL_FreeSurface(image);

		image = NULL;
	}
};
Now for the resource manager class. This is the function that loads textures into memory. It will only load a texture if it hasn't already been loaded in, and will return the surface* to that texture.
// load a texture
SDL_Surface* ResourceManager::LoadTexture(string filename)
{
	// first, check if file is already in the manager list
	for(int i = 0; i < (int)textures.size(); i++)
	{
		// if already present, just increment references, and return the pointer
		if(textures[i].filename == filename)
		{
			textures[i].references++;
			return(textures[i].image);
		}
	}

	// otherwise, load the file
	Texture temp;
	temp.filename = filename;
	temp.image = SDL_LoadBMP(filename);
	temp.references++;

	if(!temp.image)
	{
		printf("--- error --- loading texture file %s\n", filename);
		return(NULL);
	}

	// still have a new texture, push onto vector
	textures.push_back(temp);
	return(temp.image);
}
As far as I'm aware, this code should work. The problem is when I'm trying to use the returned pointer from LoadTexture. In other SDL programs I have simply done
SDL_Surface* ptr = someOtherPtr;
and after that I was able to blit ptr to the screen without any problems. This time however, something is going badly wrong. In my sprite class, after the resource manager is initialised obvoiusly, I call LoadTexture, and store the resulting surface pointer into sprite::image.
image = rManager->LoadTexture(imageName);
after which I attempt to blit, however, I either get a program crash, a black rectangle where the image should be, or just a blank screen. If I load the file using SDL_LoadBMP directly in my blitting function, it works, so it is not a file problem or anything. Can anyone see why this might be returning an invalid surface? If I check the data inside the returned surface it is correct, the only thing that is different, if the program actually runs, is that the pixel data is NULL for some reason. I know this has been a loooong post, and I'm sorry, but I really dont know what else to do, hopefully somebody can point out something. I'm tempted scrap this whole engine im so frustrated.

Share this post


Link to post
Share on other sites
I see your problem.

Quote:

Texture temp;
// stuff...
// still have a new texture, push onto vector
textures.push_back(temp);
return(temp.image);


The texture "temp" is destroyed at the end of the function. During destruction temp will free its SDL_Surface *. Also, elements in a vector could potentially be reshuffled, and that is a lot more times a constructor, copy constructor or destructor have a chance to be called.

I suggest using texture pointers in your vector. That way its much clearer when a texture is created or destroyed, since it is manual. An improvement would be to use a smart pointer instead of a raw one.

Remember if you use texture pointers to delete them when you're done.

Good Luck!

Share this post


Link to post
Share on other sites
Doh, yes, I see now. Thank you very much, I cant believe how long I have spent trying to figure that out, its been so frustrating.

Theres always such an obvious solution to my problems that I'm missing it seems, ah well, I'll remember this so it doesn't happen again.

Again, thank you very much for helping rip-off, now I can get back to doing some actual work. =)

Share this post


Link to post
Share on other sites

This topic is 4303 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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