Search code examples
c++texturesrenderingsfml

How to draw on a single buffer for generative art purposes


I'm actually facing a issue I can't solve by myself, using SFML I have a single shape, and I'm moving it at each frame, and then I draw it. The problem is, SFML using two buffers, the trail won't be the same on each buffer (frame) and it will give a weird blinking effect.

I need your knowledge, should I find another way of doing it, like an array of shapes that I'll extend. Or is there a way to skip the second buffer? Making this buffer a piece of paper, and my shape the brush.

sf::CircleShape circle;
//Init the circle (radius etc)
sf::Vector2f pos(0, 500);

while(!done)
{
  pos.x += 1;
  circle.setPosition(pos);
  window.draw(circle);
  window.display();
}

May you spend a nice day.


Solution

  • you can achieve that by using sf::RenderTexture which acts as the back buffer (single buffer) to make your drawing and then draw it on screen via sf::RenderWindow`

    #include <SFML/Graphics.hpp>
    
    int main()
    {
        sf::RenderWindow window(sf::VideoMode(800, 600), "SFML art");
        window.setVerticalSyncEnabled(true);
    
        sf::RenderTexture target;
        if (!target.create(window.getSize().x, window.getSize().y))
            return -1;
    
        target.clear(sf::Color::White);
        target.display();
    
        while (window.isOpen())
        {
            sf::Event event;
            while (window.pollEvent(event))
            {
                if (event.type == sf::Event::Closed)
                    window.close();
            }
    
            if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
            {
                sf::CircleShape circle(5.f, 32u);
                circle.setPosition(sf::Vector2f(sf::Mouse::getPosition(window)));
                circle.setFillColor(sf::Color::Red);
                target.draw(circle, sf::BlendNone);
                target.display();
            }
    
            window.clear();
            window.draw(sf::Sprite(target.getTexture()));
            window.display();
        }
    }