PDA

View Full Version : Full-window flickering when program is not focused



MensInvictaManet
09-13-2016, 03:30 PM
I'm encountering a flickering issue that occurs over my entire render window in my program. It only seems to occur when the program does not have focus and generally occurs when another program creates or alters it's own rendering context. For example, if I open up two copies of my program (Window A and Window B) and move the window around on Window A, Window B will flicker. If I click out of both so that they are sitting on my screen but not focused and then I (for example) right click on my task bar, they both flicker.

I've created the simplest program possible to recreate the issue. It can be found at this GitHub repo: https://github.com/MensInvictaManet/FlickeringProblem

If anyone could take a look and let me know what's going on here, it would be greatly appreciated. Since the flickering only happens when the game isn't in focus, it isn't a major issue for any game I create (I would assume the game would remain in focus while being played) but it is definitely a problem I'd like to see solved regardless. The project utilizes OpenGL through SDL and I'm not certain that isn't causing the issue, but I feel like I've seen plenty of games in SDL that utilize OpenGL without this issue, so it must be fixable.

Before anyone mentions the search bar, please know that I looked through the first four pages of responses for "flickering" and most threads weren't answered... and the ones that were, were for a different issue. Also, please note that I'm not using GLUT, so please don't respond as if I am.

john_connor
09-13-2016, 04:13 PM
dont you have a limit for the frames-per-second (in the main loop) ?
and whats with vsync, is it disabled ?

i have very old games, that also have an issue when i ALT+TAB to the desktop, the ingame time passed faster than the real time, which means that the fps isnt limited correctly (i think)

MensInvictaManet
09-13-2016, 04:29 PM
There is currently no limit on the frames per second in the primary loop, as you can see in main.cpp

There is a vsync setting being set in WindowManager.h though, when the window is created

SDL_GL_SetSwapInterval(1)

It's an SDL-to-OpenGL call and to be honest I'm not entirely sure how it works under the hood, but the documentation (https://wiki.libsdl.org/SDL_GL_SetSwapInterval) implies this is how I synchronize updates with the vertical retrace rate, which is Vsync, if I'm not mistaken.

The call isn't failing because if it is, I would see an error in the console window (which I have disabled on this example but I've used it in the past and the error is definitely not coming up)

Silence
09-14-2016, 12:05 AM
I had a very quick look at your sources.

At first glance you don't seem to use any double buffering. You even don't seem to ask for GL to flush or finish.

So, if you want to keep a single buffer, call to glFlush or glFinish at the end of each frame.
If you want double buffer, set it appropriately, then swap your buffers.

Then vsync might behave more appropriately.

For more information you might refer to this tutorial (http://www.opengl-tutorial.org/).

john_connor
09-14-2016, 05:11 AM
inline void WindowManager::Render()
{
for (auto iter = m_WindowList.begin(); iter != m_WindowList.end(); ++iter)
{
if (!(*iter).second->m_Minimized)
{
// Clear the screen
SDL_SetRenderDrawColor((*iter).second->m_Renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear((*iter).second->m_Renderer);

// Update the screen
SDL_RenderPresent((*iter).second->m_Renderer);
SDL_GL_SwapWindow((*iter).second->m_Window); // TODO: Only do this to the current window?
}
}
}


try to swap the buffers for each window anyway
if you dont, there is nothing preventing the fps from going over 3000/sek and above

MensInvictaManet
09-14-2016, 10:56 AM
Thank you for your replies. I've updated the code with a few things:

- I determine the pixel format in WindowManager and grab the Device Context Handle and allow access to it through WindowManager
- I call glDrawBuffer(GL_BACK) before rendering so that it renders to the back buffer
- I added glFlush, glFinish, and SwapBuffers to the end of the rendering (I know SwapBuffers makes glFinish irrelevant, I just added it for any viewer's piece of mind)

The project still flickers. I think this problem needs some hands-on help, though I know that's a lot to ask. If you think you know the solution and you're already on Windows with Visual C++ installed, please just run the project with your changes to see if they stop the flickering. I've tried so many potential solutions at this point and I'm running out of ideas.

If you go to ArcadiaEngine.h and set the console to be active (it's one of the flags at the top) you can see that the pixel format determination is failing, which is what enables Double Buffering, so I'm trying to work through that now. If you have any ideas, please try them out and let me know if you see a solution.

MensInvictaManet
09-14-2016, 11:43 AM
Eureka, I've figured it out. Though I could use some advice on my method, because it feels like the incorrect fix for this situation.

I went into WindowManager.h and removed the following calls:
- SDL_SetRenderDrawColor
- SDL_RenderClear
- SDL_RenderPresent

And it now works without flickering... 2D and 3D still shows up when I draw them and everything seems fine...

...but now I wonder what those calls actually did. The program works fine without them, so what were they for? Will removing them have consequences?

MensInvictaManet
10-03-2016, 02:57 PM
Bump: Still looking for an answer for that last question... Was I just using two different rendering methods and perhaps it was flickering because of switching between them?

Is this just not something I can get answered here since it isn't OpenGL-specific anymore?

Silence
10-04-2016, 01:07 AM
- SDL_SetRenderDrawColor
- SDL_RenderClear
- SDL_RenderPresent


This looks to be related to SDL only. SDL OpenGL functions generally start with SDL_GL. So you most certainly pervaded your window with OS framebuffer functionalities.