是否可以垂直同步单个缓冲上下文?

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 个不同的帧缓冲区对象?

Emacs 缓冲区内的 OpenGL 上下文

故意使 HTMLMediaElement 或 HTMLVideoElement 缓冲区无效或清除?

我是不是允许在 OpenGL 2.1 的多个共享上下文中同时从同一个缓冲区对象进行渲染?

是否可以在单火花上下文中收听两个 dtsreams?

发布单个文件以在 GitLab 上下载