11

I'm writting a game with OGL / GLFW in c++.

My game is always running at 60 fps and without any screen tearing. After doing some research, it seems that the glfwSwapInterval() function should be able to enable/disable V-sync or the 60fps cap.

However, no matter the value I pass to the function, the framerate stays locked at 60 and there is no tearing whatsoever. I have also checked the compositor settings on linux and the nvidia panel, and they take no effect.

This is a common thing I assume, is there a way to get around this fps cap?

Manu
  • 209
  • 1
  • 3
  • 13
  • 4
    You may have vsync hard enabled in your GPU driver. Search how to disable it with whatever vendor, and see if it unlocks the framerate. – ricco19 May 18 '18 at 13:41
  • 1
    10 seconds of google (GLFW vsync) led me to this: http://www.glfw.org/docs/latest/group__context.html#ga87425065c011cef1ebd6aac75e059dfa -- a way to query about your GLFW implementations implementation of extensions around tear support. When you called it what did it say about support for those extensions? – Yakk - Adam Nevraumont May 18 '18 at 13:42
  • @ricco19 I already tried that, the vsync in my driver is disabled but thank you anyways. – Manu May 18 '18 at 16:49
  • @Yakk-AdamNevraumont I tried with "GLX_EXT_swap_control" and the result was true. I take it that means swap control can be used, but shouldn't that be the glfwSwapInterval() line I tried before? – Manu May 18 '18 at 16:51
  • `glfwSwapInterval(0)` would be the programmatic way, unless you need to override it directly in a driver (GPU) control panel. – Brett Hale May 19 '18 at 09:56
  • Okay everyone, thank you for all your answers. I figured how to solve this in the end. Looks like setting `glfwSwapInterval` to 0 or 1 or other number greater than 1 just enables/disables it fully rendering it useless for the vsync purpose. Setting it to 0.5 however, tells glfw to double the framerate limit to twice your screen refresh rate (120 fps in my case) and also disables vsync. So what I did to get this working was to play with `glfwSwapInterval()` changing the value between 0 and 1. Hope this helps whoever finds this posts afterwards. – Manu May 22 '18 at 21:58
  • @Manu use `glfwSwapInterval(0)`, but call this function right after the call to `glfwMakeContextCurrent` – Eugen1344 Apr 18 '19 at 01:34

1 Answers1

16

Is there a way to remove 60 fps cap in GLFW?

The easiest way is to use single buffering instead of double buffering. Since at single buffering is always use the same buffer there is no buffer swap and no "vsync".

Use the glfwWindowHint to disable double buffering:

glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE);
GLFWwindow *wnd = glfwCreateWindow(w, h, "OGL window", nullptr, nullptr);

Note, when you use singel buffering, then you have to explicite force execution of the GL commands by (glFlush), instead of the buffer swap (glfwSwapBuffers).


Another possibility is to set the number of screen updates to wait from the time glfwSwapBuffers was called before swapping the buffers to 0. This can be done by glfwSwapInterval, after making the OpenGL context current (glfwMakeContextCurrent):

glfwMakeContextCurrent(wnd);
glfwSwapInterval(0);

But note, whether this solution works or not, may depend on the hardware and the driver.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Are you sure about GL_FALSE / GLFW_FALSE. – mouse Aug 31 '21 at 08:49
  • @mouse both are 0 – Rabbid76 Aug 31 '21 at 08:51
  • By using single buffering you'll not only get tearing, but also other glitches like e.g. half-rendered scene alternating with completely rendered version, depending on how often the driver flushes commands to the GPU before it gets actual `glFlush`. Using blocking commands like `glReadPixels` will also present half-baked scene. May be better to render to an FBO and then blit to present the complete scene. – Ruslan Aug 31 '21 at 11:01