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

Author Topic: sf::RenderTexture bug when destroyed in fullscreen  (Read 4599 times)

0 Members and 2 Guests are viewing this topic.

mazellan

  • Newbie
  • *
  • Posts: 3
    • View Profile
sf::RenderTexture bug when destroyed in fullscreen
« on: July 21, 2013, 08:24:40 pm »
Greetings everyone.

I have integrated SFML in my project development that uses some RenderTextues, Sprites,... and when try it t run in fullscreen, the entity that stores the RenderTexture is destroyed, cause some sort of flickering in the screen.

For 1-2 frames, the screen goes black and then return to normal. Trying to reproduce this problem, I've discovered what causes this comportament but not why.

In the following code, I find that when a RenderTexture is destroyed (out of scope/delete), the problem appears.

My specs are Win 7 64 bits, Nvidia 560Ti (driver version 320.49 WHQL), i5 2500k.

#include <iostream>
#include <SFML\Graphics.hpp>
#include <SFML\Window.hpp>


int main()
{
    sf::RenderWindow App(sf::VideoMode(640, 480, 32), "SFML Test", sf::Style::Fullscreen);
        App.setFramerateLimit(60);

        sf::RectangleShape rect(sf::Vector2f(300,300));
        rect.setFillColor(sf::Color::White);
        rect.setPosition(170, 100);
       
        sf::RenderTexture *tex_ptr = NULL;
       
        while (App.isOpen())
        {
                sf::Event Event;

                while (App.pollEvent(Event))
        {
            // Close Window
            if (Event.type == sf::Event::Closed)
                return 1;

                        if (Event.type == sf::Event::KeyPressed)
                        {
                                // Exit
                                if (Event.key.code == sf::Keyboard::Escape)
                                        return 1;      

                                // Each time F1 is pressed, screen goes black in some sort flickering
                                if (Event.key.code == sf::Keyboard::F1)
                                {  
                                        sf::RenderTexture tex;
                                        tex.create(200,200);
                                }

                                // Each time F2 is pressed, screen goes black in some sort flickering
                                if (Event.key.code == sf::Keyboard::F2)
                                {  
                                        tex_ptr = new sf::RenderTexture();
                                        tex_ptr->create(200,200);
                                        delete tex_ptr; // if this line is commented, does not flick
                                }
                        }
                }

                App.clear();
                App.draw(rect);
                App.display();
        }

    return 0;
}
 

mazellan

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: sf::RenderTexture bug when destroyed in fullscreen
« Reply #1 on: July 22, 2013, 02:36:29 pm »
Try it today on another computer (win 7 32 bits, nvidia 8600GT) and the result is the same "black blink" effect when Rendertexture is destroyed.

In windowed mode all run fine, smooth, without any flickering. But in fullscreen, everytime I destroy a rendertexture, or a entity that stores a rendertexture, because I don't gonna use it anymore, the flicker appears.

Try it with Vsynch enabled and same result.

¿Anyone with nvidia cards (or ati) can confirm this?

PS: I use Visual Studio 2010.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::RenderTexture bug when destroyed in fullscreen
« Reply #2 on: July 22, 2013, 02:45:36 pm »
I'll test your code and see if I can reproduce the problem.
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::RenderTexture bug when destroyed in fullscreen
« Reply #3 on: July 22, 2013, 08:33:55 pm »
I can reproduce the problem.

This is caused by a call to DestroyWindow in the destructor of WglContext, but I don't know why and how to avoid it.
Laurent Gomila - SFML developer

mazellan

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: sf::RenderTexture bug when destroyed in fullscreen
« Reply #4 on: July 22, 2013, 11:36:39 pm »
Thanks for the answer :)

¿Should I add a new track issue on github for this problem?

I hope there is a solution, somehow...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::RenderTexture bug when destroyed in fullscreen
« Reply #5 on: July 23, 2013, 07:53:56 am »
Quote
¿Should I add a new track issue on github for this problem?
Yes, you can.
Laurent Gomila - SFML developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: sf::RenderTexture bug when destroyed in fullscreen
« Reply #6 on: July 23, 2013, 08:54:13 am »
Well... the solution is quite simple to understand but would require a little change in the RenderTexture API that I'm sure won't make so big of a difference.

The problem is that SFML controls the target of OpenGL operations using many (sometimes too many ;)) OpenGL contexts. To control the destination window of OpenGL operations this makes sense, but for some reason contexts are also used to control whether or not to draw to a RenderTexture (even if the FBO implementation is being used, for the default implementation there is no other way). In a normal scenario, you would bind the FBO, do your drawing, and unbind it when you are done. For unknown reasons (probably just uniformity with the rest of SFML) Laurent chose to create the FBO in its own context and leave it bound forever, using context switching to control whether to draw to it or not as opposed to binding/unbinding. If you don't already have a context from a previously created window, this would make sense, however that is what ensureGlContext() is for. There is no point creating a new context for every RenderTexture if you can just reuse the currently active one, except if you use it for selection as mentioned above.

If RenderTexture were to use some kind of bind/unbind API then at least the FBO implementation wouldn't have to rely on contexts for target selection. This would mean less overhead and less hidden windows that are created/destroyed which would also solve this problem.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::RenderTexture bug when destroyed in fullscreen
« Reply #7 on: July 23, 2013, 09:11:54 am »
Quote
The problem is that SFML controls the target of OpenGL operations using many (sometimes too many ;)) OpenGL contexts.
True :D

Quote
For unknown reasons (probably just uniformity with the rest of SFML) Laurent chose to create the FBO in its own context and leave it bound forever, using context switching to control whether to draw to it or not as opposed to binding/unbinding
The reason is that implementation becomes straight-forward: switching a target is just a context switch internally.
If I just bind/unbind the FBO, I would also have to restore all the OpenGL states and matrices of the render-target, which may also badly interact with my states cache algorithm.

I'm not saying that it is impossible, maybe I would end up with a cleaner and more efficient implementation if I investigated in this direction; but it would require extra efforts to ensure that everything works as expected.

And yes, I would love to clean the context system. There are too many of them, and the dummy contexts with their hidden window are definitely ugly.
« Last Edit: July 23, 2013, 09:13:30 am by Laurent »
Laurent Gomila - SFML developer

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: sf::RenderTexture bug when destroyed in fullscreen
« Reply #8 on: March 24, 2014, 10:09:38 am »
So, guys, there is solution of the problem? I'm tried to deactivate RenderWindow and RenderTexture before it destroyed - still i have flickering on full screen. Or may be i can avoid the problem? I'm recreating texture when GUI window resized... May be it's better to create max sized RenderTexture and then just copy part of it to sprite... Yeah! Thank you for reading this!!! =)