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

Author Topic: Screen starts flickering when on fullscreen  (Read 4501 times)

0 Members and 1 Guest are viewing this topic.

Mutoh

  • Newbie
  • *
  • Posts: 31
    • View Profile
Screen starts flickering when on fullscreen
« on: March 06, 2014, 04:11:24 am »
This is hard to explain. Whenever my game goes fullscreen, whatever is being drawn by the main RenderWindow gets erased patches over it, in a pattern. The following drawing illustrates what would happen if my window was drawing a sprite with a black background and a red smile, if the window had a 64 bits per pixel depth VideoMode (so that the sprite could be centered in such a way) and was calling clear(sf::Color::White).



The patterns go up and down through the sprite, but in a low framerate, it appears to be rather appearing in random spots through it.

These patterns only show up when I call clear() for the RenderWindow every tick. If I don't, no patterns show up, but the game still runs "choppy". I suspect that my window is skipping one every two frames.

Everything runs perfectly when windowed.

I can show some code if the community would like, but I would rather first have some insight of what could be the possibilities. It's somewhat messy code. Can a missing .clear() call have such an effect? .display()? As in, does this have any relation to double-buffering? Has anyone even seen this before?

---

edit:

Apparently, this was the excerpt of code that was making everything go haywire:

{

                        static const float separation = 3.5f;
                        static const unsigned char white = 160;

                        sf::Text continueText("Continuar", lib::defaultFont(), lib::defaultFontSize());
                       
                        // continueText.setColor(sf::Color::White);
                        // auto continueLocal = continueText.getLocalBounds(); /*1*/
                        // auto continueBounds = continueText.getGlobalBounds(); /*1*/ /*2*/
                        // continueText.setPosition(
                                // windowWidth / 2 - continueBounds.width / 2.f - continueLocal.left,
                                // windowHeight / 2 - continueBounds.height - continueLocal.top - separation);
                               
                        sf::Text quitText("Sair", lib::defaultFont(), lib::defaultFontSize());

                        // quitText.setColor(sf::Color(white, white, white));
                        // auto quitLocal = quitText.getLocalBounds(); /*3*/
                        // auto quitBounds = quitText.getGlobalBounds(); /*3*/ /*2*/
                        // quitText.setPosition(
                                // windowWidth / 2 - quitBounds.width / 2.f - quitLocal.left,
                                // continueText.getPosition().y + continueLocal.height + separation);

                        sf::Text disclaimerText(L"O jogo está pausado", lib::defaultFont(), lib::defaultFontSize());
                        disclaimerText.move(5, 0);
                       
                        m_pauseTex.create(windowWidth, windowHeight);
                        m_pauseTex.setSmooth(true);
                       
                        m_pauseTex.clear(::pausedBlack);
                       
                        // m_pauseTex.draw(disclaimerText);
                        // m_pauseTex.draw(continueText);
                        // m_pauseTex.draw(quitText);
                       
                        m_pauseTex.display();

                        m_pauseScreen.setTexture(m_pauseTex.getTexture());
                       
                        } // This block (and subsequent deaths of the Texts) isn't actually necessary, as the bug shows up even if the following 'while' is right below the m_pauseScreen.setTexture above.

Variables with the m_ prefix are indeed member variables. m_pauseTex is an sf::RenderTexture and m_pauseScreen is an sf::Sprite.

lib::defaultFont() returns a const sf::Font& reference to a font stored in static resources. lib::defaultFontSize() returns a simple int.

This m_pauseScreen is drawn every tick by something as simple as:

while (m_window.isOpen()) {
    sf::Event event;
        while (m_window.pollEvent(event));
       
        m_window.clear();
        m_window.draw(m_pauseScreen);
        m_window.display();
}

The error shows up whenever I uncomment any of the line combinations with the numbers. For example, if I uncomment only the two lines with that /*1*/, the error would show up. If I uncommented only the two lines with the /*2*/ in the end, the error would show up as well. Same for /*3*/

In the end, it's all because of calls to sf::Text::getLocalBounds() and getGlobalBounds(). I haven't yet nailed what exactly causes the problem, and I don't think I'd even be able to. I knew sf::Text had specially buggy boundary management, but I didn't know it was extreme enough that it could interfere with completely unrelated instances; even commenting the m_renderTex.draw calls doesn't prevent the bug.

Can anyone reproduce the situation with only what I've provided? The window is created with .create(sf::VideoMode(640, 480, 64), "", sf::Style::Fullscreen);
« Last Edit: March 06, 2014, 05:42:05 am by Mutoh »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Screen starts flickering when on fullscreen
« Reply #1 on: March 06, 2014, 05:42:57 am »
Are you using a framerate limit or vertical sync?
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Mutoh

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Screen starts flickering when on fullscreen
« Reply #2 on: March 06, 2014, 05:48:32 am »
Framerate limit set to 40FPS, and vertical sync set to false. But the bug is present as well when framerate is set to 0 (unlimited) and/or vertical sync is enabled.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Screen starts flickering when on fullscreen
« Reply #3 on: March 06, 2014, 05:54:14 am »
It really sounds like screen tearing, but without a video or seeing it myself I can't say for sure. Make sure vsync is on and the framerate limit is not being used (set to 0). If that doesn't fix it measure the fps of your game (1 / frametime.asSeconds() to std::cout) and if it is higher than 60fps then vsync would seem to be disabled in your driver settings. Try forcing it on in your driver settings and see if it helps.  ;)
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
AW: Screen starts flickering when on fullscreen
« Reply #4 on: March 06, 2014, 08:19:38 am »
If it doesn't solve it, post a minimal and complete example.

Not sure of 64bit depth works properly, try 32bit for once.
« Last Edit: March 06, 2014, 08:31:34 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Mutoh

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Screen starts flickering when on fullscreen
« Reply #5 on: March 07, 2014, 01:07:01 am »
Alright, I have managed to isolate the bug. Let's see if this code reproduces the behaviour in anyone else's computer.

int main() {   
        sf::RenderTexture m_pauseTex;
        sf::Sprite m_pauseScreen;

        sf::Font corbel;
        if (!corbel.loadFromFile("data/fonts/corbel.ttf")) return 0; // Might want to change the filename

        {

        static const auto windowWidth = 640;
        static const auto windowHeight = 480;

        static const float separation = 3.5f;
        static const unsigned char white = 160;

        sf::Text continueText("Continuar", corbel, 24);

        // continueText.setColor(sf::Color::White);
        auto continueLocal = continueText.getLocalBounds();
        auto continueBounds = continueText.getGlobalBounds();
        continueText.setPosition(
                windowWidth / 2 - continueBounds.width / 2.f - continueLocal.left,
                windowHeight / 2 - continueBounds.height - continueLocal.top - separation);

        sf::Text quitText("Sair", corbel, 24);

        // quitText.setColor(sf::Color(white, white, white));
        auto quitLocal = quitText.getLocalBounds();
        auto quitBounds = quitText.getGlobalBounds();
        // quitText.setPosition(
                // windowWidth / 2 - quitBounds.width / 2.f - quitLocal.left,
                // continueText.getPosition().y + continueLocal.height + separation);

        sf::Text disclaimerText("O jogo está pausado", corbel, 24);
        disclaimerText.move(5, 0);

        m_pauseTex.create(640, 480);
        m_pauseTex.setSmooth(true);

        m_pauseTex.clear(sf::Color(0, 0, 0, 160));

        m_pauseTex.draw(disclaimerText);
        m_pauseTex.draw(continueText);
        m_pauseTex.draw(quitText);

        m_pauseTex.display();

        m_pauseScreen.setTexture(m_pauseTex.getTexture());

        }
       
        sf::RenderWindow window(sf::VideoMode(640, 480, 64), "", sf::Style::Fullscreen);

        while (window.isOpen()) {
                sf::Event event;
                while (window.pollEvent(event)) {
                        switch(event.type) {
                                case sf::Event::Closed:
                                        window.close();
                                        break;
                        }
                }

                window.clear(sf::Color::White);
                window.draw(m_pauseScreen);
                window.display();
        }
}

I have only tested Corbel and Arial, but apparently it is independent of the font used.

AlejandroCoria

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
    • alejandrocoria.games
    • Email
Re: Screen starts flickering when on fullscreen
« Reply #6 on: March 07, 2014, 01:33:06 am »
Does it make sense to use 64 as bpp? Seriously, I do not know.

sf::VideoMode(640, 480, 64)

Mutoh

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Screen starts flickering when on fullscreen
« Reply #7 on: March 07, 2014, 01:37:05 am »
In 32bpp the fullscreen automatically stretches whatever is rendered to fit the screen. In 64bpp, no scaling whatsoever is done. I prefer to leave it at 64 because then I can manually scale properly the game's graphics so that everything fits the screen while maintaining a 1:1 ratio to the original image.

AlejandroCoria

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
    • alejandrocoria.games
    • Email
Re: Screen starts flickering when on fullscreen
« Reply #8 on: March 07, 2014, 02:27:17 am »
Interesting. I always used a View to maintain 1:1 ratio, with the maximum possible size, in full screen and with any window size.

Returning to the subject.
Question for those who know: There may be problems if you create and use a RenderTexture before creating a window?

Daerst

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Screen starts flickering when on fullscreen
« Reply #9 on: March 07, 2014, 02:08:16 pm »
Question for those who know: There may be problems if you create and use a RenderTexture before creating a window?

In my current project, I use RenderTextures for internal calculations. Additionaly, the user can create a window (at any time before, during or after the calculations) to see the current progress. Whether the window is created or not, everything works fine. So, shouldn't be a problem there.

Mutoh

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: Screen starts flickering when on fullscreen
« Reply #10 on: April 05, 2014, 01:21:21 am »
Bumping this in case anyone ever comes across the same problem and bumps into my topic, so that this future internet wanderer isn't let saddened that his problem was left never answered:

This problem is caused by using an invalid VideoMode, simple as that. Using 64 bits per pixel without even checking if it was appropriate was a bad hack of mine to achieve the following:

In 32bpp the fullscreen automatically stretches whatever is rendered to fit the screen. In 64bpp, no scaling whatsoever is done. I prefer to leave it at 64 because then I can manually scale properly the game's graphics so that everything fits the screen while maintaining a 1:1 ratio to the original image.

I was pretty much getting to what I wanted by deliberately triggering an error. That'd be pretty hardcore, if it didn't actually have any side-effects.

If you want to do this, just create a screen with sf::VideoMode::getDesktopMode(); that's what it is for, after all.

EDIT: My assumptions were wrong, the error persists! Sorry, future internet wanderer.
« Last Edit: April 05, 2014, 01:37:38 am by Mutoh »