You are on page 1of 4

4/7/24, 4:15 PM c++ - Trouble with vsync using glut in OpenGL - Stack Overflow

Trouble with vsync using glut in OpenGL


Asked 10 years, 2 months ago Modified 7 months ago Viewed 8k times

I'm struggling desperately to get Vsync to work in my OpenGL application. Here's the vital stats:

I'm using Windows, coding in C++ OpenGL and I'm using FreeGLUT for my OpenGL context (double
3
buffering). I'm aware that for the swap buffer to wait for vertical sync in Windows you are required to call
wglSwapIntervalEXT().

My code does call this (as you'll see below), yet I am still getting vertical tearing. The only way I've
managed to stop it is by calling glFinish() which of course has a significant performance penalty
associated with it.

The relevant parts of my main() function look like this:

//Initiating glut window


glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize (initial_window_width, initial_window_height);
glutInitWindowPosition (100, 100);
int glut_window_hWnd = glutCreateWindow(window_title.c_str());

//Setting up swap intervals


PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL;

if (WGLExtensionSupported("WGL_EXT_swap_control"))
{
// Extension is supported, init pointers.
wglSwapIntervalEXT =
PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");

// this is another function from WGL_EXT_swap_control extension


wglGetSwapIntervalEXT =
(PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
}

wglSwapIntervalEXT (1)

init ();

glutMainLoop(); ///Starting the glut loop


return(0);

I should point out that the return from the wglInitSwapControlARB function is true, so the extension is
supported.

c++ windows opengl freeglut vsync

Share Improve this question Follow edited Mar 4, 2014 at 15:44 asked Jan 21, 2014 at 15:53
genpfault Single Entity
51.6k 11 88 142 3,005 3 39 66

Have you checked your display driver settings? They all have an option to override application-preferences for
things like MSAA, VSYNC, texture filtering, etc. If it is set to explicitly disable VSYNC then there's nothing you can
do except for change the driver setting to respect application preferences. You may have forced adaptive VSYNC

https://stackoverflow.com/questions/21262944/trouble-with-vsync-using-glut-in-opengl?rq=3 1/4
4/7/24, 4:15 PM c++ - Trouble with vsync using glut in OpenGL - Stack Overflow
on in the preferences not knowing exactly how that worked... it allows the screen to tear at framerates <
RefreshHz but keeps the application from drawing more than RefreshHz FPS... it cuts down on power
consumption and tearing at high framerates. – Andon M. Coleman Jan 21, 2014 at 19:12

Adaptive VSYNC can also be requested at the application level, if your implementation supports
WGL_EXT_swap_control_tear . You can request it by passing -1 to wglSwapIntervalEXT (...) . On the right
hardware in Windows Vista/7/8 you do not even need VSYNC while drawing in windowed mode. On all of my AMD
hardware I can draw at > 12,000 FPS without any tearing in windowed mode, but in fullscreen mode VSYNC is
essential. – Andon M. Coleman Jan 21, 2014 at 19:16

Thanks for the suggestions. I have tried wflSwapIntervalEXT(-1) but I still get tearing, besides I would like to run in
full screen mode. Regarding the first comment, I checked my driver settings, it was set to application preference,
but even when I forced VSYNC to be on, i'm still getting tearing. :( – Single Entity Jan 21, 2014 at 20:47

Do any other OpenGL applications on your system work with VSYNC? I am reluctant to blame GLUT for this,
because I do not think it even knows about swap intervals (the original GLUT framework did not), but it may be
setting the value of wglSwapIntervalEXT (...) before it does a buffer swap. – Andon M. Coleman Jan 21,
2014 at 21:34

1 My guess: You disables V-Sync in the driver settings in a way that it overrides all application settings. I'd check that
first before messing with the swap interval. In all drivers you can set to V-Sync by default which effectively sets the
swap interval to 1 as default value. – datenwolf Jan 21, 2014 at 22:52

4 Answers Sorted by: Highest score (default)

Ok - between the great help I've received here, and my own hours of research and messing around with
it I've discovered a few things, including a solution that works for me (in case others come across this
8 problem).

Firstly, I was using freeGLUT, I converted my code to GLFW and the result was the same, so this was
NOT an API issue, don't waste your time like I did!

In my program at least, using wglSwapIntervalEXT(1) DOES NOT stop vertical tearing, and this was
what led to it being such a headache to solve.

With my NVIDIA driver set to VSYNC = ON I was still getting tearing (because this is equivalent to
SwapInterval(1) which doesn't help) - but it was set correctly, the driver was doing what it should have
been I just didn't know it because I was still getting tearing.

So I set my NVIDIA driver to VSYNC = 'Application preference' and used wglSwapIntervalEXT(60)


instead of 1 which I had always been using, and found that this was actually working because it was
giving me a refresh rate of about 1Hz.

I don't know why wglSwapIntervalEXT(1) doesn't Vsync my screen, but wglSwapIntervalEXT(2) has the
desired effect, though obviously I'm now rendering every other frame which is inefficient.

I found that with VSYNC disabled glFinish DOES NOT help with tearing, but with it enabled it does (If
anyone can explain why that would be great).

So in summary, with wglSwapIntervalEXT(1) set and glFinish() enabled I no longer have tearing, but I
don't understand still why.

Here's some performance stats in my app (deliberately loaded to have FPS's below 60):

wglSwapIntervalEXT(0) = Tearing = 58 FPS

wglSwapIntervalEXT(1) = Tearing = 58 FPS

https://stackoverflow.com/questions/21262944/trouble-with-vsync-using-glut-in-opengl?rq=3 2/4
4/7/24, 4:15 PM c++ - Trouble with vsync using glut in OpenGL - Stack Overflow

wglSwapIntervalEXT(2) = No tearing = 30 FPS

wglSwapIntervalEXT(1) + glFinish = No Tearing = 52 FPS

I hope this helps someone in the future. Thanks for all your help.

Share Improve this answer Follow answered Jan 22, 2014 at 12:04
Single Entity
3,005 3 39 66

i am also having problem with vsync and freeglut. previously i used glut, and i was able to selectivly
enable vsync for multiple GLUT-windows.
0
Now with freeglut, it seems like that the wglSwapIntervalEXT() has no effect. What has effect is the
global vsync option in the NVIDIA control panel. If I enable the vsync there, i have vsync in both of my
freeglut windows, and if i disable i dont have. It does not matter what i set specificly for my application
(in the nvidia control panel). Also this confirms what i observe:

if(wglSwapIntervalEXT(0))
printf("VSYNC set\n");
int swap=wglGetSwapIntervalEXT();
printf("Control window vsync: %i\n",swap);

the value of swap is always the value that is set in the NVIDIA control panel. Does not matter what is
want to set with wglSwapIntervalEXT().

Otherwise here you can read what the GLFinish() is good for: http://www.opengl.org/wiki/Swap_Interval

I use it because i need to know when my monitor is updated, so i can synchronously execute tasks after
that (capture with a camera something).

Share Improve this answer Follow answered Mar 4, 2014 at 14:45


Vizsnyiczai Gaszton
39 1 1 4

I know this question is quite old, but I'll answer anyway, more as a reminder to myself if I encounter this
issue again than anything. When setting up the Pixel Format for your "presenting" context (the one that'll
0 be responsible for calling SwapBuffers ), you HAVE to use WGL_DOUBLE_BUFFER_ARB as an attribute.
Otherwise SwapBuffers will just copy the current back buffer to the window buffer and ignore the swap
interval (as there is no swap occuring)

Share Improve this answer Follow answered Sep 2, 2023 at 11:47


Tab
81 1 11

As described in this question here, no "true" VSync exists. Using GLFinish is the correct approach. This
will cause your Card to finish processing everything it has been sent before continuing and rendering the
-1 next frame.

You should keep track of your FPS and the time to render a frame, you might find GLFinish is simply
exposing another bottleneck in your code.

https://stackoverflow.com/questions/21262944/trouble-with-vsync-using-glut-in-opengl?rq=3 3/4
4/7/24, 4:15 PM c++ - Trouble with vsync using glut in OpenGL - Stack Overflow

Share Improve this answer Follow edited May 23, 2017 at 12:34 answered Jan 21, 2014 at 16:24
Community Bot Mike D
1 1 69 1 4

1 I maybe wrong but I was under the impression that GLFinish would introduce a bottleneck because it forces a sync
between the CPU and GPU, I'm sure I've read that somewhere? Also, in that post you suggested (which I had
already read) it was suggested that the person should use the Swap Interval approach which is what I've done, but
it isn't working. – Single Entity Jan 21, 2014 at 16:51

Have you thought about throttling the rendering thread yourself? – Mike D Jan 21, 2014 at 16:55

Yes I've thought about it. But from what I've read I shouldn't have to, which is why I'm hoping someone out there
knows why the swap interval approach is compiling and running but not doing anything – Single Entity Jan 21,
2014 at 17:14

3 framerate throttling is a really bad idea. And V-Sync is perfectly possible in OpenGL. The basic principle is that after
a SwapBuffers call the next function call that would alter the contents of the back buffer is hold back until the buffer
swap actually happened. So either the OpenGL command queue fills up until calls block. Anyhow with V-Sync
enabled the framerate will be capped to the V-Sync rate. – datenwolf Jan 21, 2014 at 22:51

https://stackoverflow.com/questions/21262944/trouble-with-vsync-using-glut-in-opengl?rq=3 4/4

You might also like