tags:

views:

1056

answers:

1

I've created a WPF application using C# that renders about 50 3D elements and animates the camera in order to move around the scene.

While it all works, I've noticed as the camera moves, ugly video tearing occurs.

I'm well aware of the standard cause of tearing, ie the application is updating frames at a different rate from the monitor/adapter vertical sync.

I've also read that the default screen update rate in WPF is 60 frames per second and that on XP WPF updates without regard to the montior v-sync.

For certain scenes the tearing is less noticeable, but often it is distracting enough to be a real problem.

I'm really hoping there is a resolution, after all Windows Forms has had double buffering for years. Moving to WPF is actally a backward step for many types of application if there is no resolution.

So, on Windows XP, how can I configure WPF to remove tearing?

I'm looking for more helpful answers then "move to Vista". This is simply out of the question for many of the future users of this application.

+1  A: 

No answers yet, surely with the number of WPF developers out there someone else has seen this problem?

In the meantime I've investigated/read some more and have come across the Timeline.DesiredFrameRate property.

With my display running at 50hz vertical refresh I tried setting this to 50 FPS in the hope this would brings things in sync. Unfortunately this had no effect on the tearing.

However, I did have to apply it to a single specific animation I created (in code) using BeginAnimation(). I'm not sure how this would affect a "global" framerate at all.

Instead, I would have expected to need to do this at a more global level, say on the viewport, however I couldn't find DesiredFramerate property on the viewport object.

Another area to look at could be the RenderCapability.Tier but I haven't had the time to look in detail yet.

[Update]

No solution but a useful tip. To set the DesiredFramerate globally (ie for all animations in the viewport) you can override the PropertyMetadata for the Timeline.DesiredFrameRateProperty dependency property:

// Set the global desired framerate to 50 frames per second
Startup += delegate(object sender, StartupEventArgs e)
{
Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline),
     new PropertyMetadata(50));
};

It's best to place this in the constructor of the standard WPF Application class.

Unfortunately this didn't solve my problem because even setting it to FPS, it must not be synced accurately enough with monitor v-sync.

It is handy to know about though, particularly if you have slow moving animations and want to save CPU usage by setting the FPS much lower then the default 60fps.

[Update]

Setting the DesireFrameRate to some very high value such as 100+ seems to reduce but not remove the flicker. One big drawback however is that the CPU (on my 4 yo PC) goes to 35%.

Ash