Segmentation fault during copying data from sf::Image to tgui::Texture

Started by GetterSetter, 06 April 2024, 22:02:00

GetterSetter

Hello, the following line of code gives me a segmentation fault during execution and I don't know why:
texture.loadFromPixelData(smg.getSize(), smg.getPixelsPtr());
//smg - sf::Image;
//texture - tgui::Texture;
I definitely know that sf::Image is loaded correctly and is not empty.
The call stack:
tgui::Backend::createTexture() (Unknown:0)
tgui::Texture::loadFromPixelData(tgui::Vector2<unsigned int>, unsigned char const*, tgui::Rect<unsigned int> const&, tgui::Rect<unsigned int> const&, bool) (Unknown:0)
Backend::GetTextureFromClipboard() (Backend.hpp:37)
main() (test.cpp:41)
UPD: I've rebuilt tgui with debug flag and I have the following message from tgui::getBackend():
TGUI assertion: getBackend() was called while there is no backend
test: /.../LIBS/TGUI-1.2.0/src/Backend/Window/Backend.cpp:77: std::shared_ptr<tgui::Backend> tgui::getBackend(): Assertion `globalBackend != nullptr' failed.

Okay, I've got the idea. I must have some backend (i.e. tgui::Gui), but why?

texus

That assertion means you are trying to create the Texture before the Gui has been constructed.

GetterSetter

Quote from: texus on 06 April 2024, 22:18:37That assertion means you are trying to create the Texture before the Gui has been constructed.
oh, yes, I haven't updated the page and haven't noticed your reply, but why do I need some backend to create a texture?

texus

TGUI doesn't just support SFML, it can also be used with e.g. SDL or GLFW. I designed the library so that it could be built with multiple of these backends simultaneously and that the backend would be selectable at runtime. The downside of that is that until the backend code is loaded, TGUI has no idea which implementation of tgui::Texture it should use (loading the image is completely different in SFML vs SDL).

So somewhere at the beginning of your code you need to initialize the SFML_GRAPHICS backend after which you can actually use TGUI (as loading the backend initializes the internals of the library). While you can manually create the backend object, for simplicity it is tied to the Gui object by default. If you create the Gui object, it will automatically initialize the backend if no backend was loaded yet. This however means that unless you manually initialize the backend, you must load the Gui object before you do anything else with the TGUI library.

Essentially creating and destroying the Gui object acts like global TGUI_Init() and TGUI_Destroy() functions.

One extra detail to note: if the Gui object is created WITHOUT a window, then the backend still won't be initialized until the gui is given a window, so a window needs to be attached to the gui before you can load the texture (because only then does TGUI have access to the OpenGL context from the SFML window).

GetterSetter

Now I've got that, thank you for your comprehensive explanation. I thought that tgui::Texture is something like a container for pixels and it doesn't depend on a backend implementation but it turned out that it actually does. I truly appreciate your help and your work!