我在 WinForms 应用程序中以每秒 18.66666 帧的速度运行动画(它以 140 BPM 的速度与音乐同步,这就是帧速率奇怪的原因)。动画的每个cel都是预先计算好的,动画由高分辨率的多媒体定时器驱动。动画本身很流畅,但我看到大量的“撕裂”,或者由于屏幕刷新中途捕获 cels 而导致的伪影。
当我将我的程序渲染的一组 cels 写入 AVI 文件,然后在 Windows Media Player 中播放 AVI 文件时,我根本没有看到任何撕裂。我假设 WMP 可以流畅地播放文件,因为它使用 DirectX(或其他东西)并且能够将呈现与屏幕的刷新事件同步。它不会改变帧速率,因为动画与音频保持同步。
这就是 WMP 能够在不撕裂的情况下渲染动画的原因,还是我遗漏了什么?有什么方法可以使用 DirectX(或其他东西)让我的程序知道当前扫描线在哪里,如果是这样,有什么方法可以使用该信息来消除撕裂而无需实际使用 DirectX用于显示细胞?还是我必须完全使用 DirectX 进行渲染才能处理这个问题?
更新:忘记了一个细节。我的应用程序使用 Graphics.DrawImage 将每个单元格渲染到 PictureBox 上。这是否比使用 BitBlt 慢很多,这样我可以通过使用 BitBlt 至少消除一些撕裂?
更新2:我看到的效果绝对不是闪烁(与撕裂不同)。我的面板是双缓冲的,为 AllPaintingInWmPaint、UserPaint、OptimizedDoubleBuffer 等设置控件样式,覆盖 onPaintBackGround 等。所有这些都是消除闪烁所必需的,但撕裂问题仍然存在。当动画具有非常快速移动的对象或从亮到暗变化非常快的对象时,这一点尤其明显。当物体缓慢移动并且不会快速改变颜色时,撕裂效果就不太明显(因为连续的 cel 总是彼此非常相似)。
最佳答案
当您的图像更新与显示器的刷新率不同步时,就会发生撕裂。监视器显示部分先前图像和部分新图像。当图像中的物体快速移动时,效果非常明显。
它在 Windows 窗体中无法修复,您无法获得视频适配器的垂直同步信号。你可以在DirectX app .
关于c# - 如何消除动画撕裂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2448831/