views:

211

answers:

2

I'm writing an animation app in C#/WinForms (see this question). Basically, the animation in my application is smooth but shows tearing effects; when I take the same animation and render it to an AVI file and play it with Windows Media Player, the animation shows no tearing effects at all. I know WMP is not changing the frame rate because the animation is synchronized with music.

I assume WMP uses DirectX or some other technology that is aware of the monitor's refresh rate and scanline position etc., but I always assumed that programming to the refresh rate would constrain the frame rate. Obviously this isn't the case with WMP.

Does anyone know anything about how WMP (or other video players) renders video internally? I've searched but I can't seem to find any details about this.

+1  A: 

Are you painting each frame of your animation to a memory bitmap first, and then blitting the bitmap to your window? If not, this might be the solution for you.

(this is, of course, in addition to double-buffering)

Dmitry Brant
I was going to put a disclaimer on the question referencing double-buffering, along with setting control styles, overriding OnPaintBackground and all the other stuff you have to do to avoid flicker, in the hopes of convincing people that I really am having a tearing problem. :)
MusiGenesis
+3  A: 

It's been a while since I did any DirectX programming, so this may be out of date.

From what I remember, with DirectX you could set up a flipping chain of buffers, usually three buffers: the buffer being displayed, the buffer to be displayed and the buffer being written to. On an update, DirectX will wait for a V-sync before updating the displayed buffer. Now, this will cause a discrepency between the displayed image and the image that should be displayed, but this will be, at most, one refresh, about 1/60th of a second, so you're unlikely to notice.

Some ASCII art to show what I mean:

|-|-|-|-|-|-|-|-|-|-|-|-|-|-|  - screen refresh
|----|----|----|----|----|---  - animation 
|-----|---|-----|---|-----|--  - displayed
Skizz
Crap, it looks like this is what I'll have to do. I was hoping I could do something simpler, like only use DirectX to tell me when the monitor was in the vertical blank period, and postpone my rendering until the VBP. Unless I'm misunderestimating this, this would eliminate tearing at the cost of occasional little hiccups in motion.
MusiGenesis