如何消除动画撕裂?动画

2023-09-03 03:38:07 作者:何必再高傲

我在18.66666运行在一个WinForms应用程序的动画......每秒帧数(它是同步的音乐在140 BPM,这就是为什么帧速率很奇怪)。每个动画的cel是$ P $对计算,并且动画是由高分辨率多媒体计时器驱动。动画本身是平稳的,但我看到一个显著量撕裂,或者说导致CELS文物被抓中途屏幕刷新。

I'm running an animation in a WinForms app at 18.66666... frames per second (it's synced with music at 140 BPM, which is why the frame rate is weird). Each cel of the animation is pre-calculated, and the animation is driven by a high-resolution multimedia timer. The animation itself is smooth, but I am seeing a significant amount of "tearing", or artifacts that result from cels being caught partway through a screen refresh.

当我拿一套CELS我的节目呈现,并把它们写出来的AVI文件,然后播放Windows Media Player中的AVI文件,我看不到任何撕裂的。我认为WMP播放该文件顺利,因为它使用DirectX(或其他),并能够同步与屏幕的刷新活动的渲染。它不改变帧速率,作为动画保持同步与音频

When I take the set of cels rendered by my program and write them out to an AVI file, and then play the AVI file in Windows Media Player, I do not see any tearing at all. I assume that WMP plays the file smoothly because it uses DirectX (or something else) and is able to synchronize the rendering with the screen's refresh activity. It's not changing the frame rate, as the animation stays in sync with the audio.

这究竟是为什么WMP能够渲染动画没有流泪,还是我失去了一些东西?有没有什么办法可以使用​​DirectX(或其他),以使我的程序要注意的地方当前扫描线,如果是的话,有没有什么办法可以使用​​这些信息来消除撕裂实际上并没有使用的DirectX用于显示的CEL?或者,我必须完全使用DirectX渲染,以解决这个问题呢?

Is this why WMP is able to render the animation without tearing, or am I missing something? Is there any way I can use DirectX (or something else) in order to enable my program to be aware of where the current scan line is, and if so, is there any way I can use that information to eliminate tearing without actually using DirectX for displaying the cels? Or do I have to fully use DirectX for rendering in order to deal with this problem?

更新:忘记了一个细节。我的应用程序使得每个单元上使用Graphics.DrawImage一个图片。比使用的BitBlt,这显著慢,使得我可能消除至少一些撕裂通过使用BitBlt的?

Update: forgot a detail. My app renders each cell onto a PictureBox using Graphics.DrawImage. Is this significantly slower than using BitBlt, such that I might eliminate at least some of the tearing by using BitBlt?

更新2 :我看到的绝对不是忽悠(这是撕裂不同)的影响。我的面板双缓冲,设置控件样式AllPaintingInWmPaint,UserPaint,OptimizedDoubleBuffer等,覆盖onPaintBackGround等。所有这些都是必要消除闪烁,但撕裂问题仍然存在。当动画已经从光变为暗非常快非常快速移动的物体或物体它显得格外突出。当对象是缓慢移动并且不迅速改变颜色,撕裂效应小得多引人注目(因为连续透明片总是很彼此相似)。

Update 2: the effect I'm seeing is definitely not flicker (which is different from tearing). My panel is double-buffered, sets the control styles for AllPaintingInWmPaint, UserPaint, OptimizedDoubleBuffer etc., overrides onPaintBackGround and so on. All these are necessary to eliminate flicker, but the tearing problem remains. It is especially pronounced when the animation has very fast-moving objects or objects that change from light to dark very quickly. When objects are slow-moving and don't change color rapidly, the tearing effect is much less noticeable (because consecutive cels are always very similar to each other).

推荐答案

撕裂发生在你的形象更新是不符合显示器的刷新率同步。监视器显示了previous形象,新形象的一部分的一部分。当图像中的对象移动快,效果相当显着。

Tearing occurs when your image update is not in sync with the refresh rate of the monitor. The monitor shows part of the previous image, part of the new image. When the objects in the image move fast, the effect is quite noticeable.

这是不是可以解决Windows窗体中,你不能给显示卡的垂直同步信号。您可以在的DirectX应用。

It isn't fixable in Windows Forms, you can't get to the video adapter's v-sync signal. You can in a DirectX app.