Search code examples
c++sfml

SFML: Draw only once and render forever


I am trying to write an application in C++ to draw static 2D pieces of stuff on the screen. The guides on SFML say to do the following

while (window.isOpen())
{
    sf::Event evnt;
    while (window.PollEvene(&evnt))
    {
        /* Handle events */
    }
    window.clear();
    window.draw(/* 2D stuffs go here */);
    window.display();
}

But I don't want to waste my resources drawing the same graphic over and over again. Is there a way to draw only once (before the while loop) and display forever (inside the while loop)?

P.S. - I tried to bring window.clear() and window.draw() outside the main loop. But the screen flickers.


Solution

  • You can use a sf::RenderTexture to draw your static objects. Then you create a sf::Sprite that uses that texture and use it to draw them at once.

    sf::RenderTexture bgTex;
    bgTex.create(windowWidth, windowHeight);
    bgTex.draw(your_object_1);
    bgTex.draw(your_object_2);
    // the rest of the static objects
    bgTex.display() // important !
    sf::Sprite background(bgTex.getTexture());
    

    Now you only have to draw that sprite instead of repeatedly draw all objects. That's quite a time optimization.

    window.clear();
    window.draw(background); // single call :D
    window.draw(...); // draw your dynamic objects
    window.display();
    

    Edit: Also, notice that the sf::RenderTexture still can be modified if you want, and the sprite using it will reflect the changes. So if you want to change the background, you only have to clear-draw-display on bgTex once and not worry about any other thing.