在opengl中使用Glut的Vsync麻烦

Trouble with vsync using glut in OpenGL

本文关键字:Vsync 麻烦 Glut opengl      更新时间:2023-10-16

我拼命地努力让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函数返回是正确的,因此支持扩展。

ok-在我在这里收到的巨大帮助与我自己的研究时间和处理它之间,我发现了一些事情,包括一个对我有用的解决方案(如果其他人遇到这个问题)。

首先,我在使用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()启用了我不再撕裂,但我不知道为什么。

这是我的应用程序中的一些性能统计数据(故意加载以使FPS低于60):

  • wglswapintervalext(0)=撕裂= 58 fps
  • wglswapintervalext(1)=撕裂= 58 fps
  • wglswapintervalext(2)= no Tearing = 30 fps
  • wglswapintervalext(1) glfinish = no Tearing = 52 fps

我希望将来对某人有所帮助。感谢您的所有帮助。

我也对vsync和freeglut有问题。以前我使用了Glut,并且能够选择为多个Glut Windows启用Vsync。

现在使用FreeGlut,WGLSWAPINTERVALEXT()似乎没有效果。具有效果的是NVIDIA控制面板中的全球Vsync选项。如果我在那里启用vsync,我的两个freeglut窗户都有vsync,如果我禁用我没有。我对应用程序(在NVIDIA控制面板中)的特定设置都无关紧要。另外,这证实了我观察到的内容:

if(wglSwapIntervalEXT(0)) 
printf("VSYNC setn");
int swap=wglGetSwapIntervalEXT();
printf("Control window vsync: %in",swap);

交换的值始终是NVIDIA控制面板中设置的值。使用wglswapintervalext()。

设置什么都没关系。

否则,您可以在这里阅读Glfinish()对:http://www.opengl.org/wiki/swap_interval

我使用它是因为我需要知道显示器何时更新,因此我可以同步执行任务(用相机捕获某物)。

我知道这个问题很旧,但是无论如何,我会回答,如果我再次遇到这个问题,则更多地提醒自己。为您的"介绍"设置像素格式时上下文(将负责调用SwapBuffers的负责),您必须将WGL_DOUBLE_BUFFER_ARB用作属性。否则,SwapBuffers只会将当前的后缓冲区复制到窗口缓冲区,而忽略交换间隔(因为没有互换)

如下所述,不存在" true" vsync。使用Glfinish是正确的方法。这将导致您的卡完成在继续并渲染下一个帧之前发送已发送的所有内容。

您应该跟踪FPS和渲染框架的时间,您可能会发现Glfinish只是在代码中揭露另一个瓶颈。