Texture Class

Started by Danetta, 21 January 2017, 07:56:32

Danetta

Hello.

I spent some time writing resource manager, but then I noticed that tgui::Picture, unlike sf::Sprite, doesn't need it Texture to be alive after setTexture has been called. Is it true? If so, I can get rid of all the ptrs I used because it will work just fine like this:

1. Create/Load sf::texture.
2. Bind texture to tgui::Picture.
3. Don't care about sf::Texture anymore, tgui::Picture has stored the object itself and not a pointer.

How is it implemented? Is there any unneeded work transfering the texture? Or it just pointer transformed into something like shared_ptr so it will be saved without any additional memory management?

Also, what's the purpose for tgui::Texture class? I saw some widgets require it, but they also fine with sf::Texture.

texus

TGUI has its own tgui::Texture class which can be shared between widgets.
If you load a picture by filename then it will use an internal texture manager that keeps track of which files were loaded already and reuse the same texture when it is used multiple time. If you however pass an sf::Texture then it has no idea when you are reusing the same texture (as it doesn't store a pointer to it), so a copy will always be made. You could share the tgui::Texture manually if you care about this by first copying the sf::Texture to a tgui::Texture and then passing this tgui::Texture to your widgets (which will only copy the tgui::Texture wrapper and share the internal sf::Texture).

At least in 0.8-dev (the class has the same purpose in 0.7 but is slightly different), widgets just take the tgui::Texture as parameter which can get implicitly converted from either a filename or an sf::Texture. Classes like tgui::Texture and tgui::Color are mainly just an abstraction that allow implicit conversions (e.g. when a widget needs a color, you can pass either an sf::Color or a string like "red" because the parameter is defined as a tgui::Color).

Danetta

Well, I am loading textures from memory (because they are loaded via sf::http), so I probably still need to use sf::Texture?

Just got slightly confused, because in sfml documentation it's said that Sprite contains only a pointer to texture, while tgui::Picture contains the texture itself and it mentioned nowhere.

texus

You will still have to use an sf::Texture, but if you want multiple widgets to use this texture without copying it every time then you can wrap it in a tgui::Texture:
Code (cpp) Select
sf::Texture sfTexture;
// load sf::Texture from memory
tgui::Texture texture{sfTexture}; // sfTexture is copied here and is no longer needed from this moment on
picture1->setTexture(texture); // texture is given to picture1 without copying the sf::Texture
picture2->setTexture(texture); // texture is given to picture2 without copying the sf::Texture
// texture no longer has to be stored because the pictures will share its contents


I don't really know how and where to document the behavior so that you can find it. It documented somewhere though: the Picture class takes an tgui::Texture as parameter for which the constructor contains the following documentation when passing an sf::Texture:
"The texture will be copied, you do not have to keep the sf::Texture alive after calling this function" (https://github.com/texus/TGUI/blob/0.8-dev/include/TGUI/Texture.hpp#L110).
I know that the abstractions make the documentation a lot harder to find, but it saves me a lot of extra functions in widgets or renderers.