在OpenGL中使用过量的vsync有问题

我拼命挣扎着让Vsync在我的OpenGL应用程序中工作。 这里是重要的统计数据:

我正在使用Windows,在C ++ OpenGL中编码,而我正在使用FreeGLUT作为我的OpenGL上下文(双缓冲)。 我知道,交换缓冲区在Windows中等待垂直同步,您需要调用wglSwapIntervalEXT()。

我的代码确实会这样(正如你将在下面看到的),但我仍然在垂直撕裂。 我设法阻止它的唯一方法就是调用glFinish(),这当然会带来与其相关的显着性能损失。

main()函数的相关部分如下所示:

//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); 

我应该指出,从wglInitSwapControlARB函数返回是真实的,所以支持扩展。

好的 – 在我收到的大量帮助和我自己的研究和搞乱的时间之间,我发现了一些东西,包括适用于我的解决方案(以防别人遇到此问题)。

首先,我使用的是freeGLUT,我将代码转换为GLFW,结果是一样的,所以这不是API问题,不要像我一样浪费时间!

至少在我的程序中,使用wglSwapIntervalEXT(1)不会停止垂直撕裂,这就是导致它很难解决的原因。

当我的NVIDIA驱动程序设置为VSYNC = ON时,我仍然在撕裂(因为这相当于SwapInterval(1)不起作用) – 但设置正确,驱动程序正在做本来应该做的事情,不知道是因为我还在撕裂。

所以我把我的NVIDIA驱动程序设置为VSYNC ='应用程序首选项',并使用wglSwapIntervalEXT(60),而不是我一直使用的1,并发现这实际上是工作的,因为它给了我一个约1Hz的刷新率。

我不知道为什么wglSwapIntervalEXT(1)不是Vsync我的屏幕,但wglSwapIntervalEXT(2)具有所需的效果,但显然我现在正在渲染每隔一个效率低的帧。

我发现VSYNC禁用glFinish不帮助撕裂,但它启用它(如果有人可以解释为什么这将是伟大的)。

所以总之,wglSwapIntervalEXT(1)set和glFinish()被启用后,我不再有撕裂,但我不明白为什么。

以下是我的应用程序中的一些性能统计(故意加载到60以下的FPS):

  • wglSwapIntervalEXT(0)=撕裂= 58 FPS
  • wglSwapIntervalEXT(1)=撕裂= 58 FPS
  • wglSwapIntervalEXT(2)=不撕裂= 30 FPS
  • wglSwapIntervalEXT(1)+ glFinish = No撕裂= 52 FPS

我希望这将有助于未来的人。 感谢你的帮助。

如此处所述,不存在“真正的”VSync。 使用GLFinish是正确的方法。 这将导致你的卡在继续和渲染下一帧之前完成处理所发送的所有内容。

你应该跟踪你的FPS和渲染帧的时间,你可能会发现GLFinish只是暴露了代码中的另一个瓶颈。

我也有vsync和freeglut的问题。 以前我使用过剩,我能够选择性地启用vsync多个GLUT窗口。

现在用freeglut,似乎wglSwapIntervalEXT()没有效果。 NVIDIA控制面板中的全局vsync选项有什么作用。 如果我在那里启用vsync,我在两个我的freeglut窗口都有vsync,如果我禁用我没有。 不要紧,我为我的应用程序(在NVIDIA控制面板)具体设置。 这也证实了我所观察到的:

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

swap的值总是在NVIDIA控制面板中设置的值。 无关紧要什么是用wglSwapIntervalEXT()设置。

否则,在这里您可以阅读GLFinish()的好处: http : //www.opengl.org/wiki/Swap_Interval

我使用它,因为我需要知道什么时候我的显示器更新,所以我可以同步执行任务后(用相机捕获的东西)。