Direct2Dの紹介

公開:2010-11-17 20:28
更新:2020-02-15 04:36
カテゴリ:windows,direct2d,c++

昨日Direct2Dがイミディエイトモードってなんだ?Direct3Dの古いバージョンにはあったけど今は無いとか書いたけど、誤りであったようだ。Direct3D6.1以前はイミディエイト・モードとリテインド・モードと言うのがあり、前者はプリミティブ描画のみで低レベルAPI、後者はシーングラフをサポートする高レベルAPIという位置づけだった。後者はシーンを保持するということでRetained Modeと名付けられたらしい。
ではDirect2Dがイミディエイト・モードだとすると、リテインド・モードにあたるのはなんなの?というとWPFのMILがそれにあたるらしい。下記に書いてあった。

Direct2D の紹介
http://msdn.microsoft.com/ja-jp/magazine/dd861344.aspx
以下該当部分の引用

WPF に詳しい読者は、前述した保持モードのグラフィックス API についてもよくご存知のことでしょう。Direct3D では、保持モードの API は廃止されましたが、WPF には、Media Integration Layer (MIL) と呼ばれる固有の内部保持モード API があります。MIL は WPF と Direct3D の中間に存在し、WPF によって定義されたシーン グラフのコピーを保持します。(中略)
Direct2D では、単純な、または複雑なジオメトリ、ビットマップ、テキストを Direct3D のイミディエイト モード グラフィックス API で直接作成してきわめて高いパフォーマンスを実現し、リッチなレンダリングをサポートします。

でそうなってくるとMILってどんなAPIなの?とか思ったんだけれど、これがよくわからない。ユーザが直接叩けるAPIではどうもなさそうである。WPFが実質MILを操作するAPIとなるのだろうね。

Direct2D の紹介」記事はとても読みやすい。ヘルプも同じ人が訳してくれればいいのに。。
この記事ではWindowフレームワークとしてWTLが使われている。懐かしい。。

「Direct2D の紹介」記事のポイント

デバイス非依存のリソースの作成とデバイス依存のリソースの作成は別メソッドに分ける

デバイス依存のリソースはロストする可能性があり、ロストすると再作成する必要がある。 デバイス非依存のリソース作成とデバイス依存のリソース作成は別メソッドに分けておくことで、デバイスロスト時のデバイス依存リソースの再作成時に再利用できる。

描画はWM_PAINTメッセージ中に行う

描画要求メッセージが来たときに描画する。描画はBeginPaint()とEndPaint()の間に行う。

デバイス依存のリソースの作成メソッドはWM_PAINTメッセージで呼び出す

デバイス依存のリソース作成メソッドはWM_PAINTメッセージで呼び出すようにする。デバイス依存のリソース作成メソッドはリソースが作成されていない時のみリソースを作成するように作る。

EndDraw()呼び出し時にデバイスロストしているかどうかHRESULTをチェックする

描画メソッドはバッチ処理なので、メソッド呼び出し時はエラーは発生しない。EndDraw()呼び出し時にキャッシュされていた描画メソッドがまとめて実行され、HRESULT値が返される。デバイスがロストするとそのHRESULTにD2DERR_RECREATE_TARGETが入るのでそれをチェックし、一致したらデバイス依存リソースをリリースする。リリースされたリソースは次のWM_PAINTメッセージで再作成する。

WM_ERASEBKGNDメッセージを捕捉し、背景を再描画されないようにする。

ちらつきを防止するためWM_ERASEBKGNDメッセージを処理し、背景を再描画されないように戻り値にTRUEを返す。

ウィンドウサイズが変化したらデバイス依存リソースを再作成する

WM_SIZEメッセージが来たらデバイス依存リソースを解放し、次のWM_PAINTメッセージで再作成する。ただレンダーターゲットは解放しなくても良い。(Resizeメソッドがあるので)

WM_DISPLAYCHANGEを捕捉し、描画する

ディスプレイ解像度の変更時のタイミングで再描画させるため。

レンダーターゲットのWindowStateをチェックし、表示されている時だけ描画する

レンダーターゲットのCheckWindowState()の戻り値をチェックし、D2D1_WINDOW_STATE_OCCLUDEDビットが立っていない時のみ描画する。

この記事はDirect2Dで描画する際に効率的に描画するためのヒントになる。こうしないとDirect2Dはダメとかいうわけではない。別にWM_PAINT中でなくても描画できるしね。

エッセンシャル WPF:Windows Presentation Foundation (Programmer’s SLECTION―Microsoft .net Development Series)