轻量级OpenGL游戏的完美V-sync实现:需要一个小信息

在游戏中我们的互联网组装团队正在编程,我们假设我们的观众中的每个人都将在游戏中获得全速。 因此,为了节省视频RAM,并希望为显卡提供更多的空闲时间,使用没有双缓冲的V-sync将是我们的最佳选择。因此,在OpenGL中,我们需要知道如何做到这一点。 根据我的理解,V-sync是指图形卡在完成渲染单帧后暂停,直到该帧完成发送到显示设备。双缓冲不会暂停渲染操作(或者可能会暂停渲染操作,或者可能是特定于实现;不确定),因为它会在复制到帧缓冲区之前绘制到第二个缓冲区,以便监视器获得完整帧或不根本就是新帧(具体来说,是帧缓冲区中最后存储的图像)。好吧,我们不需要这个功能,只要显卡只是在它需要时才写入帧缓冲区。 这是一个非常慢的在线游戏(但它非常有创意^ _ ^)。实时行动非常少。因此,非常精确的用户输入不是必需的;它可以在渲染帧之前随时从OS捕获为单个单元。 所以,为了做到这一点,我需要能够从OpenGL获得“Frame已经完成发送到监视器”的消息。可能吗?如果没有,最好的选择是什么? 该游戏目前仅针对Windows编程,但应该在几个月内完成Linux的工作。     
已邀请:
你有一种误解V-Sync的错误概念。视频RAM中有一部分以恒定速率(帧刷新率)连续发送到显示设备。因此,在发送完整帧之后立即在非常短的空白时间之后发送下一帧。但是发送帧之间的时间远远短于发送全帧所需的时间。 没有V-Sync会发生什么,对帧缓冲内容的操作是可见的,例如,如果帧以红色和绿色交替填充,并且没有V-Sync,您将在监视器上看到红色和绿色条带。为了避免这种情况,V-Sync交换显示驱动程序在发送完整帧后立即访问帧缓冲区的指针。 这让我们了解了双重缓冲的作用。没有双重缓冲,V-Sync几乎没有用处。 V-Sync触发的动作必须非常非常快速地发生。因此,这归结为交换指针或非常快速的blitting操作(可能只需为GPU的MMU设置CoW属性)。 如果没有双重缓冲且没有V-Sync效果,那么可以看到将图片逐帧渲染到帧缓冲区的过程。当然,如果渲染发生得比帧周期快,那么就会产生这样一种效果:自上而下,你会看到一个只有人口稀少的图像,其中越来越多的内容可以朝向僵尸图像看到,而在它之间的某个地方,它会触及屏幕下边缘,徘徊到顶部。交叉线将移动。 TL; DR:只需使用双缓冲并启用V-Sync进行缓冲交换。不要害怕记忆消耗。今天流通的所有GPU都有足够的RAM来轻松为双缓冲彩色平面提供内存。算一算:1920x1200 * RGB = 6MiB,即使是目前PC中最小的GPU,也能提供至少128MiB的RAM。移动设备,比如iPad 1024 * 768 * RGB = 2MiB,而32MiB用于显卡。无论如何,iPad的UI都是双缓冲的。     
您可以使用
wglGetProcAddress
获取
wglSwapIntervalEXT
的地址,然后调用
wglSwapIntervalEXT(1);
将更新与垂直同步同步。执行此操作时,您不会在垂直同步中收到消息 - 而是直到发生垂直回扫,并且屏幕已更新时,
glFlush
才会返回。所以,你有一个
WM_PAINT
处理程序,看起来像这样:
BeginPaint
wglMakeCurrent
do drawing
glFlush
EndPaint
在任何情况下都需要
glFlush
,以确保您完成的绘图被发送到屏幕。     

要回复问题请先登录注册