【发布时间】:2010-03-16 21:12:33
【问题描述】:
我在 WinForms 应用程序中以每秒 18.66666... 帧的速度运行动画(它以 140 BPM 的速度与音乐同步,这就是帧速率奇怪的原因)。动画的每个 cel 都是预先计算好的,动画由高分辨率的多媒体定时器驱动。动画本身很流畅,但我看到了大量的“撕裂”,或者是由于屏幕刷新中途捕捉到的细胞而导致的伪影。
当我将程序渲染的一组 cel 写入 AVI 文件,然后在 Windows Media Player 中播放 AVI 文件时,我根本看不到任何撕裂。我假设 WMP 可以流畅地播放文件,因为它使用 DirectX(或其他东西)并且能够将渲染与屏幕的刷新活动同步。它不会改变帧速率,因为动画与音频保持同步。
这就是为什么 WMP 能够在不撕裂的情况下渲染动画,还是我遗漏了什么?有什么方法可以使用 DirectX(或其他东西)以使我的程序知道当前扫描线的位置,如果是这样,有什么方法可以在不实际使用 DirectX 的情况下使用该信息来消除撕裂用于显示细胞?还是我必须完全使用 DirectX 进行渲染才能解决这个问题?
更新:忘记了一个细节。我的应用程序使用 Graphics.DrawImage 将每个单元格呈现到 PictureBox 上。这是否比使用 BitBlt 慢得多,这样我可以通过使用 BitBlt 至少消除一些撕裂?
更新2:我看到的效果肯定不是闪烁(和撕裂不同)。我的面板是双缓冲的,为 AllPaintingInWmPaint、UserPaint、OptimizedDoubleBuffer 等设置控件样式,覆盖 onPaintBackGround 等。所有这些都是消除闪烁所必需的,但撕裂问题仍然存在。当动画具有非常快速移动的对象或从亮到暗非常迅速地变化的对象时,这一点尤其明显。当物体移动缓慢且不快速改变颜色时,撕裂效果就不太明显(因为连续的细胞总是彼此非常相似)。
【问题讨论】:
-
您是否在单独的线程上运行渲染?
-
@Ardman:是的,渲染是在单独的线程上完成的(与 UI 线程分开)。
标签: c# .net winforms animation directx