是否可以垂直同步单个缓冲上下文?
Posted
技术标签:
【中文标题】是否可以垂直同步单个缓冲上下文?【英文标题】:Is it possible to vsync a single buffered context? 【发布时间】:2013-07-03 18:29:17 【问题描述】:我正在为使用 OpenGL 执行渲染的科学应用程序编写时间关键代码。我正在控制的设备看起来像电脑显示器。梦想是以 60 赫兹的频率刷新设备。
我尝试使用单缓冲区光栅模式,但无法让 vsync 正常工作。在双缓冲模式下它可以工作。
你可以对单个缓冲上下文进行 vsync 吗?
作品
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
没用
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
编辑
在我的渲染循环结束时
glFlush();
glFinish();
swapBuffers();//GDI?
【问题讨论】:
在双缓冲中,wglSwapBuffers
调用会等到下一个 vsync。使用单缓冲,您可以在一个连续的命令序列中直接渲染到流。你认为哪个函数调用应该等到下一个 vsync ?
在 Direct3D 中,您可以调用IDirect3DDevice9Ex::WaitForVBlank
。我很确定 OpenGL 没有标准函数来阻止调用线程,直到 VSYNC 中断发生,但是有一些特定于供应商的扩展。
在单缓冲模式下,有glFlush()
,基本上相当于glSwapBuffers()
。
@YohanDanvin: glSwapBuffers
暗示 glFlush
/glFinish
,但反之则不然。您可以轻松地在每帧中拥有多个刷新栅栏(如果您渲染到辅助缓冲区然后将其用作源纹理,您会这样做)
我知道。我的评论更针对@Mikhail 提示提示:您应该提供有关您正在做什么以及“不起作用”的意思的更多信息。
【参考方案1】:
为了使缓冲区交换与屏幕刷新同步(vsync 所做的),您实际上需要有多个缓冲区来交换。因此,双缓冲将是必要的。
双缓冲后启用 vsync 的方式取决于平台,尽管如 a.lasram 所示,WGL_EXT_swap_control 扩展在 Windows 上提供此功能。
【讨论】:
出于所有实际目的,是的。【参考方案2】:在过去使用 CRT 显示器时,可以在单缓冲模式下进行垂直同步。当电子束从屏幕的右下角返回到左上角时,会有几毫秒的延迟——垂直同步间隔——如果你可以在这段短暂的时间内完成所有的渲染,那么屏幕会平滑更新而不会撕裂.
真正的核心程序员在 Atari 400/800 和 Amiga 个人电脑等控制台上通过“竞速”获得更多时间来渲染,在扫描电子束之前从上到下更新帧缓冲 RAM。
你今天仍然可以做这样的事情。您可以在 Michael Abrash 的博客中找到详细信息: http://blogs.valvesoftware.com/abrash,他详细介绍了 Oculus Rift VR 耳机的延迟问题。
但这取决于了解CPU、系统总线和显示输出的确切时序细节;并且还能够用汇编程序或低级 C 编写并控制调度和中断。使用双缓冲是一种非常简单的方式。
【讨论】:
【参考方案3】:GDI 和 OpenGL 没有 VSYNC 控制。
事实上,OpenGL 并不控制渲染缓冲区的存在并将其留给系统。在windows上,WGL通过扩展WGL_EXT_swap_control控制VSYNC
【讨论】:
以上是关于是否可以垂直同步单个缓冲上下文?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 opengl 中从 2 个不同的线程渲染 2 个不同的帧缓冲区对象?
故意使 HTMLMediaElement 或 HTMLVideoElement 缓冲区无效或清除?