Sign in to follow this  

[SDL] Duplicating SDL_Surfaces

This topic is 4203 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

I've built a class in my game for a BitmapFont, which takes a spritesheet of characters and stores each character as an SDL_Surface. I've also made a copy constructor for this class as I need to properly duplicate the surface pointers. Now, as outlined in the SDL docs, this is the proper way to duplicate a surface:
  SDL_Surface *Srfc1, *Srfc2;
  Srfc1= IMG_Load("foo.png");
  Srfc2= Srfc1;
  Srfc2->refcount++;
  ..
  SDL_FreeSurface(Srfc1);
  SDL_FreeSurface(Srfc2);

...and I've actually successfully made a copy constructor for another class that only holds one SDL_Surface using this example. However, in my BitmapFont class, I have an array of 256 SDL_Surface pointers, so I need to iterate through and duplicate each surface. Here's my code:
BitmapFont::BitmapFont(const BitmapFont &oldFont)
{
   // copy pointer data
   for (int i = 0; i < 256; ++i)
   {
      characters[i] = oldFont.characters[i];
      characters[i]->refcount++;
   }   
}

It would appear to work correctly, except the program blows up whenever I assign a BitmapFont object to another BitmapFont object and it invokes the copy constructor. Even stepping through with a debugger, it would seem that everything's been copied correctly; also, the first frame is drawn on the screen right before the program quits, and in that split-second I can make out the new copy of my font being drawn on the screen, which would suggest that it does work, and that something else later is the problem. But the program works fine after commenting out where the copy constructor is invoked. Any ideas?

Share this post


Link to post
Share on other sites
How is it assigned? Does it actually invoke the copy constructor or the assignment operator? If the latter is the case - can't say I remember the exact rule in C++ - you may need to overload the assignment operator too. Other than that, I don't see anything wrong with what you have posted.

A little off topic, but what I liked to do is wrapping these bald sdl_surface pointers up in a class, doing what you did with copying a single pointer (and assigment!) and calling SDL_freeimage in the destructor. This way you can use the 'smart' sdl_surface pointers in the standard containers and don't worry about memory management or c arrays. Plus they obey scope too.

Good luck with debugging.

EDIT: you could initialize all pointers in the array to NULL and put in an assert oldFont.characters[i]; in the copy constructor loop for catching bugs, imo something like this will make your class safer.

Share this post


Link to post
Share on other sites
Hmm... it is done with the assignment operator actually... I think that still invokes the copy constructor, but I'll overload it anyway to see what happens.

That's a good idea with the wrapper class for an SDL_Surface, I think I'll give that a shot, too.

Share this post


Link to post
Share on other sites
For assignement the operator=(const font& f) function is called (ofcourse, where 'font' is your class), not the copy constructor. See if that works.

Also, why are you making a surface for each character? I made a little bitmapped font, too. This is all just my opinion, but wouldn't it be better if you have one big surface and just characters pointing to that surface appropriately?

Basically what I mean is that you have a 16x16 in ascii order bitmap which you load and have this:

SDL_Rect chars[256];

Where each rect is in ascii order. Then, for example:

chars['a'].x = a_x_place_in_sheet;
chars['a'].y = a_y_place_in_sheet;
...

Then you just call SDL_BlitSurface with the whole sheet and chars[the_char] as the source.

(Ofcourse, a loop would simplify the above stuff...)
</opinion>

Share this post


Link to post
Share on other sites
Ah, yes, the assignment operator needed to be overloaded, that's what was catching it!

Still gonna implement the SDL_Surface wrapper as suggested... seems a lot cleaner that way.

agi_shi, well, actually, I think I will do that next... I did it this way at first because I got all gung-ho about making a game and didn't think of alternatives and such at that point... just kinda wanted to throw something together to see if it actually would work. I'll probably implement a system like that next.

Thank you both for your help!

Share this post


Link to post
Share on other sites

This topic is 4203 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