Stumped by SFML behaviour

Hello. I'm having a weird problem while learning SFML. I drew an image on a window on certain coordinates using sf::shape. Later, I changed the coordinates to some other position and recompiled. The image was drawn in the new position but the old image in its old position was still there! The code no longer specifies this old location, so I assume that the window's surface is saved somewhere in memory, and since it wasn't cleared, it draws both the old and the new images.

I would think that terminating the program would eliminate the image from memory, but it doesn't. Do I have to specify this elimination through code?

What really stumps me is the following question: Who is instructing the program to draw the old shape?

I deleted the old executable and recompiled, and got the same result.

I know I could be using Window.Clear(), but as far as I know, that just refreshes the screen, but I don't know if it also destroys the older image. How do I know if it isn't lingering in memory somewhere?

Here's the code I used:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "SFML/Graphics.hpp"

int main()
{
	sf::RenderWindow ventana2;
	ventana2.Create(sf::VideoMode(800,600,32),"Ventana de Prueba");
	
	bool Running = true;
	while (Running)
	{
		sf::Event evento;
		while (ventana2.GetEvent(evento))
		{
			if (evento.Type == sf::Event::Closed)
			{Running = false;}

			if ((evento.Type == sf::Event::KeyReleased) && (evento.Key.Code == sf::Key::Escape))
			{Running = false;}
		}
		ventana2.Display();
		sf::Shape Polygon;
		Polygon.AddPoint(200, 200,  sf::Color(255, 0, 0),     sf::Color(0, 128, 128));
		Polygon.AddPoint(230, 230,   sf::Color(255, 85, 85),   sf::Color(0, 128, 128));
		Polygon.AddPoint(230, 260,  sf::Color(255, 170, 170), sf::Color(0, 128, 128));
		Polygon.AddPoint(200, 290,  sf::Color(255, 255, 255), sf::Color(0, 128, 128));
		Polygon.AddPoint(170, 260, sf::Color(255, 170, 170), sf::Color(0, 128, 128));
		Polygon.AddPoint(170, 230,  sf::Color(255, 85, 85),   sf::Color(0, 128, 128));
		ventana2.Draw(Polygon);

		/* This is the old shape. It gets drawn as well

		ventana2.Display();
		sf::Shape Polygon;
		Polygon.AddPoint(100, 100,  sf::Color(255, 0, 0),     sf::Color(0, 128, 128));
		Polygon.AddPoint(130, 130,   sf::Color(255, 85, 85),   sf::Color(0, 128, 128));
		Polygon.AddPoint(130, 160,  sf::Color(255, 170, 170), sf::Color(0, 128, 128));
		Polygon.AddPoint(100, 190,  sf::Color(255, 255, 255), sf::Color(0, 128, 128));
		Polygon.AddPoint(70, 160, sf::Color(255, 170, 170), sf::Color(0, 128, 128));
		Polygon.AddPoint(70, 130,  sf::Color(255, 85, 85),   sf::Color(0, 128, 128));
		ventana2.Draw(Polygon);
		
		*** end of comment */

	}
	return EXIT_SUCCESS;
}



I'm compiling with g++ on Linux Mint 9, Fluxbox edition, using the following:

g++ sfml_test.cpp -o sfml_test.o -lsfml-system -lsfml-graphics
I know I could be using Window.Clear(), but as far as I know, that just refreshes the screen


That's what you should be doing. Clear clears the screen, it doesn't refresh anything. If you don't clear the screen, you'll be drawing on top of garbage (in this case, you happen to be drawing on top of some video memory that you drew on previously).

How it generally works is like this:

- Clear() the screen so you start with a clean drawing canvas
- draw whatever you want onto the canvas
- Display() to make your newly drawn canvas visible
Who is instructing the program to draw the old shape?

The real question is "Who is instructing to clear the old shape?"

AFAIK sf::RenderWindow::Clear() only clears the contents of the window and doesn't modify objects in any way

I know I could be using Window.Clear(), but as far as I know, that just refreshes the screen, but I don't know if it also destroys the older image. How do I know if it isn't lingering in memory somewhere?

I think there's only one image in memory no matter how many times you draw it on the screen (someone please correct me if I'm wrong)

EDIT: too slow...
Last edited on
I'm not very familiar with SFML, but if it works anything like DirectX (and I assume it does), if you don't clear the video buffer every frame, you'll be drawing on top of what was there before.

EDIT: what Disch said.
Last edited on
Thanks for the quick and useful replies!

Alas, being a total newbie, I still have some questions. I'd very much appreciate any light on this subject:

Well, I Clear() the screen and indeed it shows only the new shape, but my main concern still applies. I'll try to phrase this correctly:

- The shape I just created gets assigned a place in memory (0xbf9f7269, according to pointers).
- After Clear(), the variable still has this address assigned to it.
- After terminating the program, does this space in memory becomes available for other programs to use?

That is my concern, that if I load a ton of images in a game, those images will remain in RAM after the user exits the program, slowing down the computer.

Which leads me to this question: Before I used Clear(), where was this 'dirty' canvas being stored?
Last edited on
I think you're mixing things up a bit. You don't get direct access to video memory. The library tells the system to draw something, the system passes it on to the driver, and the driver passes it on to the device.

Your pointer points to a memory address that refers to the computer's RAM, not the VRAM. So the data used to draw the image will still be there (since you'll probably want to use it again for the next frame), but the VRAM will be "cleared" with some filler color (in DirectX you'd pass it a color value, perhaps SFML uses some default color). Then you draw what you have to draw on top of this cleared canvas.
Last edited on
- The shape I just created gets assigned a place in memory (0xbf9f7269, according to pointers).


This is correct. Although that particular address may be different every time.

- After Clear(), the variable still has this address assigned to it.


Clear() doesn't change any of your shapes in any way. All it does is clear the frame buffer. It has absolutly nothing to do with any of your shapes, sprites, etc, etc.

The frame buffer is like a piece of paper. You draw on it and then you show it to the user with Display()

Clear() just gives you a new, blank piece of paper to draw on.

If you don't call Clear(), you'll keep drawing on the same old dirty piece of paper when you try to draw the next screen.

- After terminating the program, does this space in memory becomes available for other programs to use?


Yes, but this has nothing to do with Clear()


Before I used Clear(), where was this 'dirty' canvas being stored?


It's a buffer used internally by SFML (or really by OpenGL, which SFML uses).

Generally double buffering works like so:

There are to canvases, one of which is the "display" and one of which is the "frame buffer". Both of these buffers are owned and managed by SFML/OpenGL so you don't have to worry about where the memory is and whether or not it will be freed. The libs take care of all of that for you.

The display is what the user actually sees. And the frame buffer is what the program is currently drawing.

When when you Clear(), it just erases everything on the frame buffer. When you draw shapes, it draws them onto the frame buffer.

Calling Display() effectively quickly copies the frame buffer to the display, so that whatever you drew becomes visible to the user. (Note that it might not actually be a copy, it might be a buffer flip, in which case your frame buffer will also be changed by calling Display -- but that's a detail you don't really need to worry about).



EDIT: this time I was too slow!
Last edited on
You're right, filipe, I think I'm confusing terms here. If it's not too much to ask, do you know of any reference where I could read up about these processes (assigning and clearing data from RAM and VRAM)?

Thanks again!

EDIT:

And thanks to you too, Disch, a very thorough and clear answer.

By the way, Somebody here (I think it was albatross) told me that you were working on a SFML game. After I get the hang of the lib, I'd be more than willing to offer you my assistance, if you don't mind taking on an apprentice :D
Last edited on
Assigning and clearing data to and from RAM is what you do all the time when you write and run a program. The VRAM is something you won't have to worry about (except for knowing its limits) because libraries will do that for you. As Disch explained, graphics libraries usually keep internal buffers (triple buffering is not uncommon) and only the front buffer is drawn. What's being drawn to the screen is usually called the front buffer, and when you call a function like Display(), it first draws everything to a back buffer before it flips the buffers (could be as simple as a pointer swap) and sends data on its way to the device.

If you're interested in graphics programming, perhaps a book would be the best way to know these things in depth, although all I know comes mainly from a few chapters from Frank Luna's book on Direct3D 9 and an Evil Steve's online tutorial for D3D9 (don't have the link here, but Google it if you're interested) as well. All graphics libraries will have a lot of things in common, so once you learned how one of them works, it's easy to understand the generality in it.
Last edited on
I appreciate your answers, thanks a lot. That's all I need for now. I'll flag this thread as solved :D
By the way, Somebody here (I think it was albatross) told me that you were working on a SFML game. After I get the hang of the lib, I'd be more than willing to offer you my assistance, if you don't mind taking on an apprentice :D


A kind offer, but I'll have to pass.

My pace might be too slow for you. These days I have difficultly finding time where I am able to code. I've been working on this project for months now and it still doesn't really do anything worth showing.

I hang out in the IRC channel though if you ever want to talk about each others projects. Or at least I'm there when I'm not at work.

IRC info: http://www.cplusplus.com/forum/lounge/28548/
Topic archived. No new replies allowed.