Does loading an image in the same surface free the old image? - c++

I'm new to SDL and, in this part of my program, I would like to be able to change the image of an existing surface. My question is, will this automatically unload the previous image or will I have to use SDL_FreeSurface() and then reload the surface altogether? I don't want to end up with a large amount of images loaded that don't need to be loaded. Visual explanation:
string path = "Image.png";
SDL_Surface* loadedSurface = IMG_Load((path.c_str());
If I use loadedSurface again with a different image, will the original one be unloaded?
path = "NewImage.png";
loadedSurface = IMG_Load(path.c_str());
Or will I have to do something like this every time I load a new image:
SDL_FreeSurface(loadedSurface);
path = "NewImage.png";
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
This may be alright, I'm just not sure if creating a new surface every loop will be more intensive than another, easier way. Thank you!

You need to call SDL_FreeSurface before loading a new surface and overwriting the old pointer.
Think about it: at the point you call IMG_Load the second time, SDL is just loading the image, and doesn't know what you're going to do with the returned pointer. So it can't free any of the already loaded surfaces. You have to do that yourself.

Related

Reloading TTF_Font* for just changing pointsize using TTF_OpenFontRW?

I want to be ablte to dynamically resize the text that I rendered to the screen with my TTF_Font* object. The way I am doing it right now is, I close the font
TTF_CloseFont(font);
and then just open it right after using the new point size
font = TTF_OpenFont(filepath, new_pointsize);
Now my question is, is this the efficient way to do things? Does that mean that every time I reload my font, changing the pointsize, I delete the in-memory structure of my font and then a new one is created meaning I read the whole file from disk again?
Now in order to make it more efficient, I would like to keep my .ttf-file in memory somehow and just change the size of it. Is that possible?
I was trying to do something with SDL_RWops but I didn't succeed. Here is what I did in my load function:
font_rw = SDL_RWFromFile(filepath, "r");
font = TTF_OpenFontRW(font_rw, 0, pointsize);
and in my reload function:
TTF_CloseFont(font);
font = TTF_OpenFontRW(font_rw, 0, pointsize);
Now the problem is, that the font is not being loaded correctly, so I get NULL back as the return value for the TTF_OpenFontRW in reload.

Changing image bitmap or drawing bitmap on image causes image to disappear

I'm using two bitmaps to draw graphs on them. After drawing I need to show bitmap pictures in two Images. Assigning bitmap to Image or drawing bitmap to Image sometimes causes Image to disappear (you can see form background).
I have tried this:
Image->Picture->Bitmap->Assign(bitmap1);
Image2->Picture->Bitmap->Assign(bitmap2);
Image->Picture->Graphic = bitmap1;....
Image->Canvas->Draw(0,0,bitmap1);....
Image->Picture->Bitmap->Canvas->Draw(0,0,bitmap1);
If I don't have Sleep(100) between Image and Image2 redrawing, Image2 isn't visible for the most of the time. Also adding Image2->Refresh helps, but the issue still sometimes occurs to both Images.
If I save created bitmaps or Images to .jpeg files, all .jpeg images are correct and none of them are empty. Also Image->height, Image->picture->bitmap->height and width is always correct.
Can anyone tell me, what I'm doing wrong?
After a while I realised, that bitmaps and Images, which I saved, weren't all correct. If I was unable to see picture, it wasn't fully drawn. There were no errors, it occurred randomly, but I found out, that once program started to ignore my drawing commands, it didn't draw anything until the end of the function, which does drawing.
So - to check, if I can still draw, before assigning bitmap to Image, I did this:
Image3->Canvas->Pixels[y][0] = clRed;
TColor test = Image3->Canvas->Pixels[y][0];
Image3->Canvas->TextOut(y, 0, Device1->name);
TColor test2 = Image3->Canvas->Pixels[y][0];
if(test == test2)
{
imageUpdated = false;
delete Image3;
return;
}
Image->Picture->Graphic = Image3;
imageUpdated = true;
It means - I changed one pixel red, and after that printed over text, which should make that changed pixel white. Based on that I checked, if the color changed (was able to change pixel color and print text).
I really don't know reason, why it sometimes starts to ignore drawing commands, but I hope, that if someone runs into the same issue as I did, this answer might help him/her.

SDL delete an image and replace it with the new one

I've started SDL just a few days ago and I'm having a problem
I tried to erase an image from the screen and replace it with the new one
here is my logic :
load image
apply surface, then delay for 1s
free old image surface (SDL_FreeSurface())
load new image
apply surface
The problem is the image is still there. (it didn't get erased, just stacked with the new image)
The screen doesn't work like you think it does. You cannot "delete" something from a screen buffer, you can only write new things to the screen buffer. To 'erase' something you need to write the "background" over it.
Some game loops just re-write the entire screen with the background every frame.
This probably belongs over at gamedev.stackexchange.com

dereferencing SDL_Surfaces?

is there any way to copy a SDL surface to another, like creating a backup copy, without modifying the original when the copy is modified? *surface = *original_surface dosnt work. SDL_Surface does not have any constructors, so i cant do anything like surface = new SDL_Surface (original_surface). currently, i am opening the original image constantly, but it takes longer to open the image than for one loop to finish. this causes a lot of lagging, and eventually errors, causing my program to end
You can create a new compatible surface:
copy = SDL_CreateRGBSurface(flags, width, height, original->format.BitsPerPixel,
original->format.Rmask, original->format.Gmask,
original->format.Bmask, original->format.Amask);
And then blit the original into the copy:
SDL_BlitSurface(original, NULL, copy, NULL);

How to save to a bitmap in MFC C++ application?

I am just starting with MFC so please be tolerant ;).
I have wrote (it was mostly generated to be honest) a simple application which should do the Paint chores: drawing lines, rectangulars, ellipses, changing a color of object to be drawn etc.
I need to save what has been drawn on the screen into a bmp file. Any ideas how can I achieve this ?
I do not know if that's relevant but I am drawing objects on the screen without the use of any CBitmaps or things like that. Here is a part of code responsible for drawing :
CPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
Anchor.x=point.x;
Anchor.y=point.y;
OldPoint.x=Anchor.x;
OldPoint.y=Anchor.y;
if(pDoc->shapeCount>=MAX_SHAPES) return;
pDoc->shapeCount++;
if(bFreehand)
{
pDoc->m_shape[pDoc->shapeCount-1] = new Shape;
pDoc->m_shape[pDoc->shapeCount-1]->shape = ePoint;
}
if(bLine)
{
pDoc->m_shape[pDoc->shapeCount-1] = new CLine;
pDoc->m_shape[pDoc->shapeCount-1]->shape = eLine;
}
if(bRectangle)
{
pDoc->m_shape[pDoc->shapeCount-1] = new CRectangle;
pDoc->m_shape[pDoc->shapeCount-1]->shape = eRectangle;
}
if(bEllipse)
{
pDoc->m_shape[pDoc->shapeCount-1] = new CEllipse;
pDoc->m_shape[pDoc->shapeCount-1]->shape=eEllipse;
}
pDoc->m_shape[pDoc->shapeCount-1]->x=point.x;
pDoc->m_shape[pDoc->shapeCount-1]->y=point.y;
pDoc->m_shape[pDoc->shapeCount-1]->x2=point.x;
pDoc->m_shape[pDoc->shapeCount-1]->y2=point.y;
pDoc->m_shape[pDoc->shapeCount-1]->Pen=CurrentPen;
pDoc->m_shape[pDoc->shapeCount-1]->Brush=CurrentBrush;
bButtonDown=true;
SetCapture();
I have found this way to do it but I don't know how to obtain screen width and height to fill it in the CreateBitmap parameter's list
CBitmap *bitmap;
bitmap.CreateBitmap(desktopW, desktopH, 1, 32, rgbData);
CImage image;
image.Attach(bitmap);
image.Save(_T("C:\\test.bmp"), Gdiplus::ImageFormatBMP);
The CreateBitmap call only requires the desktop width and height if the image you wish to save is actually the entire size of the screen. If that's indeed your intent, you can use CWnd::GetDesktopWindow() to get a CWnd object that you can query for its width and height:
http://msdn.microsoft.com/en-us/library/bkxb36k8(v=VS.80).aspx
That gets dodgy in general...if for no other reason than multi-monitor scenarios...so I'd recommend against it unless you really feel like writing a screen capture app.
What you probably want to do isn't to take a full screen shot, but just save the contents of your program's window. Typically you'd do this by breaking out the drawing logic of your program so that in the paint method you call a helper function that is written to take a CDC device context. Then you can either call that function on the window-based DC you get in the paint call or on a DC you create from the bitmap to do your save. Note that you can use a CBitmap in CDC::SelectObject:
http://msdn.microsoft.com/en-us/library/432f18e2(v=VS.71).aspx
(Though let me pitch you on not using MFC. Try Qt instead. Way better.)