我正在运行一个18.66666的WinForms应用程序中的动画.帧每秒(它与音乐同步在140 BPM,这就是为什么帧速率是奇怪的)。动画的每一个单元都是预先计算出来的,动画由一个高分辨率多媒体定时器驱动。动画本身是平滑的,但是我看到了大量的“撕裂”,或者是在屏幕刷新过程中捕捉到的cels造成的工件。
当我将程序呈现的一组cels写到一个AVI文件中,然后在中播放AVI文件时,我根本没有看到任何撕裂。我假设WMP能够平稳地播放该文件,因为它使用了DirectX (或其他一些东西),并且能够将呈现与屏幕的刷新活动同步。它没有改变帧速率,因为动画与音频保持同步。
这就是为什么WMP能够在不撕裂的情况下渲染动画,还是我遗漏了什么?我是否可以使用DirectX (或其他什么)来让我的程序知道当前扫描线在哪里,如果是的话,我是否可以使用这些信息来消除撕裂,而不用实际使用DirectX来显示cels呢?或者,为了解决这个问题,我必须充分使用DirectX进行渲染吗?
更新:忘记了一个细节。我的应用程序使用PictureBox将每个单元格呈现到一个Graphics.DrawImage上。这是否比使用BitBlt要慢得多,这样我至少可以通过使用BitBlt消除一些撕裂吗?
更新2:我看到的效果肯定不是闪烁(这与撕裂不同)。我的面板是双缓冲的,为AllPaintingInWmPaint、UserPaint、OptimizedDoubleBuffer等设置控制样式,重写onPaintBackGround等等。所有这些都是消除闪烁所必需的,但撕裂问题仍然存在。特别是当动画中有非常快的物体或物体从光到黑暗变化非常快的时候。当物体移动缓慢且不迅速改变颜色时,撕裂效应就不那么明显了(因为连续的cels总是非常相似)。
发布于 2010-03-15 17:30:55
当您的图像更新与监视器的刷新速率不同步时,会发生撕裂。监视器显示前一个图像的一部分,新图像的一部分。当图像中的物体快速移动时,效果是相当明显的。
它在Windows窗体中是不可修复的,您无法访问视频适配器的v同步信号。你可以在一个DirectX应用程序。
发布于 2010-03-15 17:20:36
在我目前正在进行的项目中,我尝试了双重缓冲的想法,但没有取得很好的效果。最后,我创建了以下内容:
现在,您有一个奇怪的动画率,所以撕裂几乎肯定与屏幕更新速度和屏幕刷新速率之间的不匹配有关。在屏幕刷新过程中,您正在更新屏幕,因此屏幕在屏幕顶部绘制旧框架,在屏幕底部绘制新框架。如果您可以同步帧速率和显示刷新速率,撕裂应该消失。
发布于 2010-03-15 16:48:22
您最好使用directx (或opengl)来执行这些任务。但是,如果您只想使用winforms,请使用DoubleBuffered属性。
https://stackoverflow.com/questions/2448831
复制相似问题