My project has an option to toggle between fullscreen and windowed mode through the user interface. The main problem is when I go into fullscreen mode, I momentarily see the window mid-transition to fullscreen (I can briefly see a windows 7 style title bar, random glitches, etc). This is not a major issue, but solving it will help me understand the interaction between GLFW and my own code better. I’m on Windows 10 and Nvidia (latest for both). There are no GL or GLFW errors. The application is single-threaded. I have windowWidth, windowHeight, and goToFullscreen global variables.
My loop looks like:
Update
- updates core code and UI with windowWidth and windowHeight. sets goToFullscreen to either true or false.
Render
- sets viewport to windowWidth and windowHeight and renders the scene
glfwSwapBuffers
glfwPollEvents
- can trigger GLFWwindowrefreshfun (inside which calls Render and glfwSwapBuffers again, useful for any type of window resize, not just fullscreen)
MakeFullscreen
- if goToFullscreen is true, calls glfwSetWindowMonitor(glfwWindow, monitor, 0, 0, videoMode->width, videoMode->height, videoMode->refreshRate);
- automatically triggers GLFWframebuffersizefun, which updates windowWidth and windowHeight
RendererResize
- called whenever windowWidth or windowHeight changes from previous frame, including when resizing window manually, or when graphics quality changes (doesn’t affect UI):
- glFinish(probably unnecessary)
- internal GL FBO/texture resize
Here’s a printout during a fullscreen (starting and ending with random normal frames):
– frame count 677 –
Update at 1280 720
Render at 1280 720
glfwSwapBuffers
glfwPollEvents
– frame count 678 –
Update at 1280 720
Render at 1280 720
glfwSwapBuffers
glfwPollEvents
MakeFullscreen
GLFWframebuffersizefun at 1296 759
GLFWframebuffersizefun at 1920 1080
RenderResize at 1920 1080
– frame count 679 –
Update at 1920 1080
Render at 1920 1080
glfwSwapBuffers
glfwPollEvents
GLFWwindowrefreshfun at 1920 1080 (*1)
Render at 1920 1080
glfwSwapBuffers
– frame count 680 –
Update at 1920 1080
Render at 1920 1080
glfwSwapBuffers
glfwPollEvents
When I move the MakeFullscreen and RenderResize checks BEFORE the glfwPollEvents, I get:
– frame count 363 –
Update at 1280 720
Render at 1280 720
glfwSwapBuffers
glfwPollEvents
– frame count 364 –
Update at 1280 720
Render at 1280 720
glfwSwapBuffers
MakeFullscreen
GLFWframebuffersizefun at 1296 759
GLFWframebuffersizefun at 1920 1080
RenderResize at 1920 1080
glfwPollEvents
GLFWwindowrefreshfun at 1920 1080
Render at 1920 1080 (*2)
glfwSwapBuffers
– frame count 365 –
Update at 1920 1080
Render at 1920 1080
glfwSwapBuffers
glfwPollEvents
Both versions I can see the glitchy mid-transition state of the window for an instant. The first version effectively ignores the refresh callback (*1) because the glfwPollEvents that triggers it happens on the next frame. I’m using this version because Update and Render are always in sync with window size. The second version is cleaner but has an intermediate Render that uses out-of-date values from Update (*2), causing my UI and other things to pop for a frame. The closer refresh seems to make no difference. The glitchy effect is more pronounced in Debug mode where CPU loads are heavier, which might be why I don’t see the problem with GLFW examples.
Overall, I think I have some misconceptions about fullscreen/windowed, framebuffer size and refresh callbacks, swapbuffers, and polling. Or maybe it’s a problem outside of my code or GLFW?
Side questions:
- Why is there a 1296x759 resize?
- Why does GLFW recommend calling glfwPollEvents after glfwSwapbuffers? A loop of: {PollEvents, Update, Render, SwapBuffers, CheckClose} doesn’t seem functionally different than {Update, Render, SwapBuffers, PollEvents, CheckClose} except for the first and last frame. The documentation says:
GLFW needs to communicate regularly with the window system both in order to receive events and to show that the application hasn’t locked up. Event processing must be done regularly while you have visible windows and is normally done each frame after buffer swapping.