SFML community forums

Help => Graphics => Topic started by: shujidev on June 14, 2020, 01:25:50 am

Title: [Solved] Trying not to draw all RenderTextures at every frame
Post by: shujidev on June 14, 2020, 01:25:50 am
Hi this is my problem, I had a render texture which I fill with other textures and draw at every frame but it's not too efficient drawing all textures since they are not changing all the time, so I assumed by drawing only at some events into the main texture would be faster, except that nothing but a blinking screen is displaying, any idea what went wrong?
I have something like this:

window = new sf::RenderWindow(sf::VideoMode(1000, 800), "My window");
mainlayer = new sf::RenderTexture();
mainlayer->create(800,600)
while (window->isOpen()){
                sf::Event event;
                while (window->pollEvent(event)){
                        if (event.type==sf::Event::Closed) window->close();
                        if (event.type==sf::Event::MouseMoved) {
                                clear(mainlayer)
                                loop(layers) draw(layers,mainlayer)
                        }
                }
                window->clear(sf::Color(200,200,200,255));
                window->draw(quad);

                //clear(mainlayer)
                //loop(layers) draw(layer,mainlayer) #if I do this here, it's too inefficient

                mainlayer->display();
                sf::Sprite sprite(mainlayer->getTexture());
                window->draw(sprite);
                window->display();
        }
void draw(Layer layer, RenderTexture target){ #draw into the main texture
        clear(layer.renderTexture)
        draw(layer.curves, layer.renderTexture) #draw vertexbuffers into the texture
        drawtexture(layer.renderTexture, target) #draw texture into the main texture
}
 


If I add the drawing part into the draw function everything works fine but when I try to draw somewhere else, its as if the mainlayer was empty when I try to draw it to the renderwindow. Please help! what am I missing?
Title: Re: Trying not to draw all RenderTextures at every frame
Post by: eXpl0it3r on June 14, 2020, 07:33:26 am
Can you provide a minimal example without pseudo code?
Title: Re: Trying not to draw all RenderTextures at every frame
Post by: Hapax on June 15, 2020, 09:18:33 pm
Before displaying (display()) the render texture, it needs to be re-created from scratch i.e. cleared and drawn. If you don't change anything, don't use display on it and the texture will continue to live as it is.

Since render targets are buffered, calling display just swaps its current state from the temporary buffered state (back buffer). This can cause it to "blink".
Title: Re: Trying not to draw all RenderTextures at every frame
Post by: shujidev on June 16, 2020, 12:48:08 am
Thank you guys for your answers, I was able to recreate the program in c++ with the following code I think the problem arises after adding a ContextSettings to the RenderTextures (is antialiasing not supported on textures?)

//g++ -Wall -o "%e" "%f" -I. -L. -lsfml-graphics-2 -lsfml-window-2 -lsfml-system-2
#include "SFML/Graphics.hpp"
#include <iostream>

void displaytex(sf::RenderTexture *tex){tex->display();}
void clear(sf::RenderTarget *target){target->clear(sf::Color(255,255,255,0));}
void drawsprite(sf::Sprite *sprite, sf::RenderTarget *target, int x, int y){
        if(x!=0 || y!=0) sprite->setPosition(x,y);
        target->draw(*sprite);
}
int main(){
        sf::ContextSettings settings;
        settings.antialiasingLevel = 8;
        sf::CircleShape shape(50.f);
        shape.setFillColor(sf::Color(100, 250, 50, 155));
        shape.setPosition(0,0);
        sf::CircleShape shape2(50.f);
        shape2.setFillColor(sf::Color(250, 100, 50, 155));
        shape2.setPosition(100,0);
       
        sf::RenderWindow window(sf::VideoMode(800, 600), "My window", sf::Style::Default, settings);
        auto mainlayer = new sf::RenderTexture();
        mainlayer->create(800,600, settings);
        auto layer1 = new sf::RenderTexture();
        layer1->create(800,600, settings);
       
        while (window.isOpen()){
                sf::Event event;
                while (window.pollEvent(event)){
                        if (event.type == sf::Event::Closed)
                                window.close();
                        if (event.type==sf::Event::MouseMoved) {
                                std::cout << "mouse moved" << std::endl;
                                clear(mainlayer);
                                clear(layer1);
                                layer1->draw(shape); //drawing lots of things
                                layer1->draw(shape2); //drawing lots of things
                                displaytex(layer1);
                                sf::Sprite *sprite1=new sf::Sprite(layer1->getTexture());
                                drawsprite(sprite1,mainlayer,0,0);
                        }
                }
                window.clear(sf::Color(200,200,200,255));
                mainlayer->display();
                sf::Sprite sprite(mainlayer->getTexture());
                window.draw(sprite);
                window.display();
        }

        return 0;
}

I am still not sure what I am doing wrong, on update I clear, draw and display the textures. What would you change?
Title: Re: Trying not to draw all RenderTextures at every frame
Post by: Hapax on June 16, 2020, 10:44:51 pm
Not sure what error you are getting or what is not working in that code but I can tell you that render textures cannot use anti-aliasing.
Title: Re: Trying not to draw all RenderTextures at every frame
Post by: shujidev on June 16, 2020, 10:47:01 pm
I see, what I get is the RenderTexture is not displaying and there is a blinking black and white in the whole screen when I try to add antialiasing to their ContextSettings on creation.
Title: Re: Trying not to draw all RenderTextures at every frame
Post by: Hapax on June 16, 2020, 10:50:47 pm
It looks like you have a render texture on a render texture on a window?

Anyway, the "main layer" is only getting cleared and drawn when the event happens but is displayed regardless. It should be displayed everytime it's cleared. If you don't change anything, don't display it.
Title: Re: Trying not to draw all RenderTextures at every frame
Post by: shujidev on June 16, 2020, 11:29:41 pm
ok thank you very much I think I get it now