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

Author Topic: RenderTexture is not working corrrectly in functions (in class methods too)  (Read 1371 times)

0 Members and 1 Guest are viewing this topic.

Sanatostin

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Hellow!
I'm using SFML 2.4.2 with Code Blocks for some weeks. I've herd that RenderTexture is quite a useful thing so I tryed to use it.
When I use it in the main function then it works properly, but when i try to write the same comands in another function or class method it doesn't work correctly. I paste two pices of code that must give the same output (because the comands are almost the same) but they don't. If someone knows how to fix it or what mistake have I made, write please.
Code that works properly
#include <SFML/Graphics.hpp>
using namespace sf;

int main()
{
    //Block of the same functions
    Sprite sprite1;
    RenderTexture rendertexture;
    rendertexture.create(32, 32);
    Image im1;
    im1.create(32, 32, Color::Red);
    Texture tex1;
    tex1.loadFromImage(im1);
    sprite1.setTexture(tex1);
    sprite1.setPosition(0, 0);
    rendertexture.draw(sprite1);
    //Block of the same functions/
    RenderWindow app(VideoMode(100, 100), "SFML window");
    Sprite sprite2;
    while (app.isOpen())
    {
        Event event;
        while (app.pollEvent(event))
        {
            if (event.type == Event::Closed)
                app.close();
        }
        app.clear();
        sprite2.setTexture(rendertexture.getTexture());
        sprite2.setTextureRect(IntRect(0, 0, 64, 64));
        app.draw(sprite2);
        app.display();
    }
    return EXIT_SUCCESS;
}
 

result: red square


#include <SFML/Graphics.hpp>
using namespace sf;

Texture makeTexture()
    {
    //Block of the same functions
    Sprite sprite1;
    RenderTexture rendertexture;
    rendertexture.create(32, 32);
    Image im1;
    im1.create(32, 32, Color::Red);
    Texture tex1;
    tex1.loadFromImage(im1);
    sprite1.setTexture(tex1);
    sprite1.setPosition(0, 0);
    rendertexture.draw(sprite1);
    //Block of the same functions
    return rendertexture.getTexture();
    }

int main()
{
    RenderWindow app(VideoMode(100, 100), "SFML window");
    Sprite sprite2;
    while (app.isOpen())
    {
        Event event;
        while (app.pollEvent(event))
        {
            if (event.type == Event::Closed)
                app.close();
        }
        app.clear();
        sprite2.setTexture(makeTexture());
        sprite2.setTextureRect(IntRect(0, 0, 64, 64));
        app.draw(sprite2);
        app.display();
    }
    return EXIT_SUCCESS;
}
 

result: white square!!!
(it's not a joke. Оn my computer 1st code gives red squer, the second gives white)
Why is it so?
« Last Edit: June 09, 2017, 04:02:47 pm by Sanatostin »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
It's a case of White Square problem as described in the tutorial.

Your function returns a copy of the texture (copying textures is expensive, so not really recommended).
Then you're passing said texture directly to the sprite. The sprite however just takes a reference of the texture.
Since you didn't save the returned texture, the object will be destroyed right after you leave that line.
The sprite is now pointing to a non-existent texture, thus your sprite because a white square.

The solution is to manage textures with something like Thor's resource holder.
Additionally, you shouldn't be using Render Textures are "throw-away" objects. They are expensive to create and destroy, so you should make sure to keep them alive as long as possible and reuse whenever you can.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Sanatostin

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Thank you very much!