4

我正在用 C 语言制作一个适用于 linux 帧缓冲区的游戏。到目前为止,我有一个红色的 100x100 正方形,它与鼠标一起移动,就像一个指针一样。我已经实现了双缓冲并且它工作正常(正方形不闪烁)。问题是,横向发生了很多撕裂。我的意思是,当正方形在x轴上移动时,就像它被水平分割,它的一部分比另一部分进展得更快。如果我继续移动,这个“裂口”会在广场上从上到下缓慢传播。

我相信这是因为硬件在我将双缓冲区复制到主缓冲区的那一刻读取帧缓冲区。

我试图用 FBIO_WAITFORVSYNC ioctl 解决这个问题,但没有成功。

有什么想法可以在帧缓冲区上进行 VSync 吗?请在您的解释中添加详细信息,因为这是我第一次在基于 Linux 的操作系统上编写此类内容,因此我可能无法理解。

这是我的代码: http: //pastebin.com/KJ4iaVEL

4

2 回答 2

6

这不是进行双缓冲的正确方法。您在后台缓冲区上进行所有绘制是正确的,但随后您执行 memcpy 将数据传输到前台。在复制过程中很容易发生屏幕刷新。

要正确执行此操作,您只需切换指向数据的指针;不复制数据本身。对于 Linux 帧缓冲设备,这是通过拥有一个两倍于物理屏幕的“虚拟”屏幕并使用偏移变量来设置您是显示上半部分还是下半部分来完成的。FBIOGET_VSCREENINFO您可以使用、FBIOPUT_VSCREENINFOFBIOPAN_DISPLAY ioctl调用查询大小并设置偏移量。

此页面简要介绍了有关此的一些详细信息:http ://www.ummon.eu/Linux/API/Devices/framebuffer.html

所有相关的数据结构都在linux/fb.h头文件中。

于 2014-06-29T04:53:34.093 回答
4

不幸的是,我已经了解到@Steven Bell 的答案不太正确。尽管他是正确的,在 memcpy 期间很容易发生屏幕刷新,但正确的分辨率不是创建一个两倍于屏幕大小的虚拟帧缓冲区,并在它们之间平移,正如许多线程所暗示的那样。尝试此解决方案的任何人都会收到此处描述的错误:在 fb_var_screeninfo 中设置 yres_virtual 时出现无效参数错误

每个线程:https ://forum.odroid.com/viewtopic.php?f=55&t= 8741 不太可能真正双缓冲帧缓冲区(/dev/fb0,尽管我听说树莓派可能是此规则的一个例外)。但这并不意味着没有办法在 linux 中使用低级图形来加倍缓冲区。

这里真正的解决方案是使用 libdrm (/dev/dri/card0) 将低级图形绘制到屏幕上。这里有一个很好的例子来说明如何做到这一点:https ://github.com/dvdhrm/docs/blob/master/drm-howto/modeset-vsync.c我在尝试解决这个问题时使用了自己.

无论如何,我希望我已经拯救了我在未来解决这个问题时必须经历的令人惊讶的头痛。

于 2018-04-07T16:38:03.653 回答