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