如何摆脱 WinForms 滚动动画中的抖动?

Mus*_*sis 5 c# graphics animation

我正在用 C# 编写一个简单的控件,它的工作方式类似于图片框,但图像不断向上滚动(并从底部重新出现)。动画效果由计时器 (System.Threading.Timer) 驱动,该计时器从缓存图像(分为两部分)复制到隐藏缓冲区,然后在其 Paint 事件中将其绘制到控件的表面。

问题在于,当以每秒 20+ 帧的高帧率运行时,这种滚动动画效果会有些不稳定(在较低的帧率下,效果太小而无法感知)。我怀疑这种抖动是因为动画没有以任何方式与我的显示器的刷新率同步,这意味着每一帧在屏幕上停留的时间长度都是可变的,而不是恰好 25 毫秒。

有什么办法可以让这个动画平滑滚动?

您可以在此处下载示例应用程序(运行它并单击“开始”),源代码在此处。它看起来并不可怕,但如果你仔细观察它,你会看到打嗝。

警告:这个动画会产生一种非常奇怪的视错觉效果,可能会让你有点恶心。如果您观看它一段时间然后将其关闭,它看起来就像您的屏幕在垂直拉伸。

更新:作为一个实验,我尝试用我的滚动位图创建一个 AVI 文件。结果没有我的 WinForms 动画那么生涩,但仍然无法接受(而且看太久仍然让我感到恶心)。我想我遇到了与刷新率不同步的根本问题,所以我可能不得不坚持让人们对我的外表和个性感到厌烦。

VVS*_*VVS 3

在绘制缓冲图像之前,您需要等待VSYNC 。

有一篇CodeProject 文章建议使用多媒体计时器和 DirectX 的方法IDirectDraw::GetScanLine()

我确信您可以通过C# 中的Managed DirectX使用该方法。

编辑:

经过更多的研究和谷歌搜索后,我得出的结论是,通过 GDI 绘图并不是实时发生的,即使你在正确的时刻绘图,它实际上可能发生得太晚了,你会感到撕裂。

所以,对于 GDI 这似乎是不可能的。