问题
The CompositionTarget.Rendering event is the perfect thing to build a game's main loop upon. It basically fires at the rate of vsync (usually 60 Hz).
Occurs just before the objects in the composition tree are rendered. The Rendering event is routed to the specified event handler after animation and layout have been applied to the composition tree.
The per-frame animation how-to article explains a little bit more.
Note that your event handler method is called after layout has been computed. However, you can modify layout in your event handler method, which means that layout will be computed once more before rendering.
Based on that, the rules for code inside its handler are:
- Avoid changing layout
- Return quickly
What other gotchas are there? What non-obvious actions cause another layout pass? How much time exactly do I have inside the handler?
回答1:
I think the main purpose of it is to enable timer-free animations, such as those employing physics element like gravity, where exact regular timing is required. However it is not a good place for gaming graphics... WPF is not a gaming language and serious games will not run smoothly using it as there is too much overhead. If you want to write a .NET game, then use XNA.
From the book 'WPF Control Development Unleashed: Building Advanced User Experiences':
Some readers may recognize a similarity between this approach and higher-end graphics subsystems like DirectX. Do not mistake CompositionTarget.Rendering for a good injection point to create a WPF-based gaming graphics engine. High-end graphics and ultrahigh frame rates are not the goal of this particular aspect of WPF animation.
Similar to the DispatcherTimer approach, animations based on CompositionTarget.Rendering are also not time-bound. However, these events are synced with the render thread resulting in smoother animations than the DispatcherTimer. Also there is no need to start and stop a timer, although you may have to detach and attach the event handler to improve performance.
回答2:
While researching something else, I stumbled on this piece of advice:
The layout pass process is invoked again if any of the following actions occur:
- A child object is added to the collection.
- A LayoutTransform is applied to the child object.
- The UpdateLayout method is called for the child object. When a change occurs to the value of a dependency property that is marked with metadata affecting the measure or arrange passes.
[..]
Update Rather than Replace a RenderTransform
You may be able to update a Transform rather than replacing it as the value of a RenderTransform property. This is particularly true in scenarios that involve animation. By updating an existing Transform, you avoid initiating an unnecessary layout calculation.
来源:https://stackoverflow.com/questions/18353225/what-can-i-do-inside-compositiontarget-rendering