0

在我们的互联网组装团队正在编程的游戏中,我们假设我们的观众中的每个人都将在游戏中全速前进。

因此,为了节省视频 RAM,并希望给显卡多一点空闲时间,使用没有双缓冲的垂直同步将是我们的最佳选择。因此,在 OpenGL 中,我们需要知道如何做到这一点。

根据我的理解,垂直同步是指显卡在完成渲染单个帧后暂停,直到该帧完成发送到显示设备。双缓冲不会暂停渲染操作(或者它可能会暂停,或者它可能是特定于实现的;不确定),因为它会在复制到帧缓冲区之前绘制到第二个缓冲区,以便监视器获得完整帧或没有完全新的帧(特别是帧缓冲区中最后存储的图像)。好吧,我们不需要这个功能,只要显卡只在它该死的需要时才写入帧缓冲区。

这是一个相当慢的网络游戏(但它很有创意^_^)。很少有实时动作。因此,非常精确的用户输入不是必需的;在渲染帧之前,它可以随时从操作系统作为一个单元被捕获。

因此,为了做到这一点,我需要能够从 OpenGL 获得“帧已完成发送到监视器”的消息。是否可以?如果没有,最好的选择是什么?

该游戏目前仅针对 Windows 进行编程,但应该在几个月内完成针对 Linux 的工作。

4

2 回答 2

9

您对 V-Sync 的作用存在误解。视频 RAM 中有一部分以恒定速率(即帧刷新率)持续发送到显示设备。因此,在发送完一个完整帧后,会在很短的空白时间之后立即发送下一帧。但是发送帧之间的时间远远短于发送完整帧所需的时间。

没有 V-Sync 的情况是,对帧缓冲区内容的操作变得可见,例如,如果帧以红色和绿色交替填充并且没有 V-Sync,您将在监视器上看到红色和绿色条带。为避免这种情况,V-Sync 会在发送完整帧后交换显示驱动程序用来访问帧缓冲区的指针。

这让我们了解了双缓冲的作用。如果没有双缓冲,则 V-Sync 几乎没有用处。垂直同步触发的动作必须非常非常快地发生。所以这归结为交换指针或非常快速的 blitting 操作(可能通过简单地为 GPU 的 MMU 设置 CoW 属性)。

没有双缓冲也没有垂直同步的效果是,人们可以看到将图片逐块渲染到帧缓冲区的过程。当然,如果渲染发生得比一个帧周期快,这会产生自上而下的效果,你会看到一个只有稀疏填充的图像,越来越多的内容在底部可见,并且介于两者之间的某个地方会碰到屏幕下方的边缘,左右摇晃到顶部。相交线将移动。

TL;DR:只需使用双缓冲并启用 V-Sync 以进行缓冲区交换。不要害怕内存消耗。今天流通的所有 GPU 都有足够多的 RAM 来轻松地为双缓冲颜色平面提供内存。算一下:1920x1200 * RGB = 6MiB,即使是当今 PC 中最小的 GPU,也至少提供 128MiB 的 RAM。移动设备,比如 iPad 1024*768 * RGB = 2MiB 与 32MiB 的图形。iPad 的 UI 无论如何都是双缓冲的。

于 2011-02-04T08:49:57.157 回答
1

您可以使用wglGetProcAddress获取地址wglSwapIntervalEXT,然后调用wglSwapIntervalEXT(1);以垂直同步同步更新。执行此操作时,您不会在垂直同步时收到消息 - 而是glFlush在垂直回扫发生并且屏幕已更新之前不会返回。所以,你有一个WM_PAINT看起来像这样的处理程序:

BeginPaint
wglMakeCurrent
do drawing
glFlush
EndPaint

在任何情况下glFlush都需要,以确保将您完成的绘图发送到屏幕上。

于 2011-02-04T07:00:44.840 回答