The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
How to Reload A Surface?
Ironic


Joined: 08 Sep 2012
Posts: 9
Short Version: How can I reload/refresh a surface once I have written text onto it?

Long Version:
I am writing text on a surface and I want to change the text on the surface.
I gradually realised that once I write text to a surface it is permanently fixed so I
cannot use that surface anymore.

For my first solution I tried declaring a second surface and loading it with the same image

Code:
SDL_Surface* surface1; //Load these surfaces with same image
sDL_Surface* surface2; //Load these surfaces with same image


I then blitted surface2 onto surface1. Obviously I should have realised this does not work since then I
have to write the new text onto surface2 and I then have the same problem.

Next I tried
Code:
*surface1 = *surface2;

at the start of each loop.
For reasons I don't understand at all (I still have a lot to learn about C++) this does not
reset surface1 but instead changes surface2!

Then in desperation I tried just to load surface1 (using SDL_LoadBMP(filename)) from the file each time I called my render function
in the loop. I knew this would be bad practice but I was sure it would at least solve my problem and
let me move on with my project, but even this doesn't work! Again for reasons I just cannot
figure out when I reload the surface from the file it does not write text to it anymore.

I am really desperate for a solution on resetting the surface. I have just hit a wall and made
no progress for several days despite my best efforts. This is my last hope.
Nathaniel J Fries


Joined: 30 Mar 2010
Posts: 444
You don't want to "reset" the surface each time. Instead, keep text in its own surface, and background in its own surface. Blit background surface to screen first, then text.

IE:
Code:

SDL_Surface *bgSurface;
SDL_Surface *txtSurface;
SDL_Rect area;
[...]
bgSurface = SDL_LoadBMP(filename);
txtSurface = CreateYourTextSurface();
[...]
SDL_BlitSurface(bgSurface, NULL, screen, &area);
SDL_BlitSurface(txtSurface, NULL, screen, &area);
Nathaniel J Fries


Joined: 30 Mar 2010
Posts: 444
As for why your first solution did not work, it is because you had it backwards.
If surface1 is just the loaded image, and surface2 is the image plus text, then you want to blit surface1 to surface2 to reset it (assuming no colorkey/alpha).

Your second solution would not work because it would make both surfaces use the same memory for pixels. This is because SDL_Surface is a plain C struct, which happens to contain a pointer to where pixel data is; assigning one SDL_Surface to another SDL_Surface will make this pointer equal. This attempted solution also results in a memory leak (the memory holding the pixels for surface2 would be lost), which is a serious and often hard-to-find bug.

While SDL is really good for learning 2D graphics programming, you need to learn how to use C before you can really take advantage of it.
Ironic


Joined: 08 Sep 2012
Posts: 9
Nathaniel J Fries wrote:
You don't want to "reset" the surface each time. Instead, keep text in its own surface, and background in its own surface. Blit background surface to screen first, then text.


Thank you so much for your help! It seems so obvious in hindsight! I am going to go and try this right now!

Quote:
While SDL is really good for learning 2D graphics programming, you need to learn how to use C before you can really take advantage of it.


You are correct of course. I am trying to learn "by doing", and if I can finish the small project I am working on right now it will really help out some deserving people.
Sometimes though I just cannot figure out a way forward, I really cannot express how grateful I am that you took the time to help.