Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Is it safe to overwrite sf::Texture after calling render_texture.draw()?  (Read 199 times)

0 Members and 1 Guest are viewing this topic.

GetterSetter

  • Newbie
  • *
  • Posts: 18
    • View Profile
The problem: I have a set of textures, but they are not of the sf::Texture type. However, sometimes I need to set them to sf::RectangleShape and render them. The idea is as follows:
sf::RenderTexture rt;
rt.create(...);
rt.clear();
for(auto &texture:non_sfml_textures)
{
  sf::Texture t=convertion_function(texture);
  sf::RectangleShape rect;
  rect.setTexture(&t);

  //Setting position of rect, etc...

  rt.draw(rect);
}
rt.display();
 
Is it safe to do so? By 'safe' I mean that all the textures will be rendered correctly after calling rt.disaplay().

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10846
    • View Profile
    • development blog
    • Email
No, textures have to exist for as long as you use them and a "use" counts until you call display().
For anything else, SFML doesn't provide any guarantees.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

GetterSetter

  • Newbie
  • *
  • Posts: 18
    • View Profile
Hm, what if put rt.display() inside the loop and don't clear rt? Does it have any side effects? From my perspective, it looks like all the rendered rectangles will just stack in the texture, and that's definitely what I want, but I'm not sure if it works as I expect. No, it doesn't work like this.
The problem is that I don't want to create a whole set of texture copies just to render them, because it requires a lot of memory.
« Last Edit: April 28, 2024, 11:09:10 am by GetterSetter »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10846
    • View Profile
    • development blog
    • Email
What other kind of textures do you have anyways?

Creating a texture on the fly isn't a cheap operation.
If it's an OpenGL texture, you could also just bind it, instead of creating a copy.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

GetterSetter

  • Newbie
  • *
  • Posts: 18
    • View Profile
I have tgui::Textures. Would you mind explaining to me, please, how I can use the bind function, because it's not clear from the documentation?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10846
    • View Profile
    • development blog
    • Email
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

texus

  • Hero Member
  • *****
  • Posts: 501
    • View Profile
    • TGUI
    • Email
If you need a texture that you use for drawing in SFML and you also use for TGUI then I actually recommend loading it twice (once as sf::Texture and once as tgui::Texture), because TGUI makes no guarantees about how its texture is stored internally and whether it will be compatible with sf::Texture.

That said, you can get access to the internal SFML texture with the methods that eXpl0it3r mentioned:
const sf::Texture* pTex = &std::static_pointer_cast<tgui::BackendTextureSFML>(texture.getData()->backendTexture)->getInternalTexture();
rect.setTexture(pTex);
« Last Edit: April 29, 2024, 08:40:13 am by texus »
TGUI: C++ SFML GUI

GetterSetter

  • Newbie
  • *
  • Posts: 18
    • View Profile
Thank you, texus and eXpl0it3r! The only question I have now is whether we should use dynamic_pointer_cast instead of static_pointer_cast because we are performing a downcast.

texus

  • Hero Member
  • *****
  • Posts: 501
    • View Profile
    • TGUI
    • Email
dynamic_pointer_cast will return a nullptr if the backend texture is of a different type, while static_pointer_cast assumes the type is correct and has undefined behavior if the backend texture is of a different type.

As long as you use the SFML_GRAPHICS backend, you can be certain that the backend texture always has type BackendTextureSFML, so the cast will always succeed and a static_pointer_cast is fine. Also, there is no point in using dynamic_pointer_cast if you aren't going to check whether the return value is a nullptr or not.
TGUI: C++ SFML GUI

GetterSetter

  • Newbie
  • *
  • Posts: 18
    • View Profile
Got it, thank you!