HASTCounter:6036Today:1Yesterday:1Online:7TweetCompositionTarget.Renderingを使ったアニメーションの描画AboutここではCompositionTargetクラスのRenderingイベントを利用した描画の更新について解説します。CompositionTarget.Renderingイベントは対象の描画面(サーフェース)が更新される度に通知されるイベントです。CompositionTarget.Renderingによる描画面の更新通知は、ウィンドウの移動やサイズの変更などに関わらず常に発生し続けます。描画面の更新は、公式には"フレームの更新"とされます。ふつうWPFで何かを動かす描画(アニメーション)を実現するときは、Storyboardクラス(コンポーネント)を利用するか、あるいは定期的に処理を実行する実装(Timerクラス)によって、一定時間ごとに描画を更新するなどの処理を行う必要があります。Microsoftが提供するDirectXやXNAなどのAPIないしフレームワークでは、ゲームループと呼ばれる仕組みが提供されていますから、それらを利用する方法もあります。CompositionTarget.Renderingイベントによる実装では、これらの処理を実装するための煩わしさがなく簡単に実装できる代わりに、フレームレートに多少の乱れが生じ、制御する機能も標準的に用意されていない、という特徴があります。msdn公式のサンプルが公開されています。4.5サンプルの実行結果サンプルの実行結果は次の通りです。Windows8にCorei7(3.4GHz)で実行していますが、フレームレートは56~59fps当たりを行き来して、大体60fpsに近い値で動作しています。ウィンドウを移動する瞬間などに値が跳ね上がることが確認できています。サンプル解説することはほとんどありません。公式のサンプルも比較的シンプルです。Windowを含むGUIコンポーネントのコンストラクタなどでCompositionTarget.Renderingイベントにイベントハンドラを追加します。追加されたイベントハンドラは対象のコンポーネントが更新されるタイミング、フレームの更新のタイミングで実行されます。サンプルに用意したイベントハンドラではフレームレート(fps)を計測し、適当な数の適当なEllipseをランダムに生成してCanvasへ追加しています。フレームレートの算出方法やその他の実装内容についてはここでは解説しません。生成するEllipseの数などを変更して負荷の変化を確認するなどしてみてください。別のスレッドなどで定期実行されている処理を描画面に反映するために利用する場合には、非常に有効であると言えます。定期実行される処理の実装を行わなくて良いので、実装に手間がかかりません。別スレッドで定期実行されているのであればそちらの処理で描画するように設計すればよい、というようにも思えますが、WPFではGUIコンポーネントのオブジェクトは異なるスレッドから操作できない、という決まりがあります。このような問題は通常であればInvokeなどを利用して回避するのですが、CompositionTarget.Renderingで解決できるのであれば、一番簡単でしょう。フレームレートを厳密に考慮しなくて良いが、ほぼ固定化されたフレームレートが必要で、そのための実装に手間をかけたくない、という場合には非常に有用化と思います。ゲームには使えないかまずフレームレート(FPS)をシビアに考慮しなければならないゲームなどの実装を目的として利用するべきではありません。XNAが提供するゲームループのように、固定されたフレームレートを実現することが標準ではできません。フレームレートを維持するために処理を待たせたりスキップしたりする枠組みを実装する必要が出てきます。CompositionTargetを利用することも出来るでしょうが、他に定期実行するための処理を実装する方法もありますから、CompositionTargetを選択する理由にはならないハズです。Refresh?フレームレートの問題についてはStackoverflowの記事が参考になります。著作権Administrator。