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

Author Topic: [Solved] Trying not to draw all RenderTextures at every frame  (Read 1625 times)

0 Members and 1 Guest are viewing this topic.

shujidev

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
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?
« Last Edit: June 16, 2020, 11:30:02 pm by shujidev »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: Trying not to draw all RenderTextures at every frame
« Reply #1 on: June 14, 2020, 07:33:26 am »
Can you provide a minimal example without pseudo code?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hapax

  • Hero Member
  • *****
  • Posts: 3346
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Trying not to draw all RenderTextures at every frame
« Reply #2 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".
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

shujidev

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: Trying not to draw all RenderTextures at every frame
« Reply #3 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?
« Last Edit: June 16, 2020, 12:50:57 am by shujidev »

Hapax

  • Hero Member
  • *****
  • Posts: 3346
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Trying not to draw all RenderTextures at every frame
« Reply #4 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.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

shujidev

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: Trying not to draw all RenderTextures at every frame
« Reply #5 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.

Hapax

  • Hero Member
  • *****
  • Posts: 3346
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Trying not to draw all RenderTextures at every frame
« Reply #6 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.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

shujidev

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: Trying not to draw all RenderTextures at every frame
« Reply #7 on: June 16, 2020, 11:29:41 pm »
ok thank you very much I think I get it now