DirectX 9の描画命令 (2)
ここではDirectX 9の真の描画関数について分類を試みる.DirectX 9の真の描画関数とは以下の12のメソッドである.
- IDirect3DDevice9::Clear
- IDirect3DDevice9::ColorFill
- IDirect3DDevice9::DrawIndexedPrimitive
- IDirect3DDevice9::DrawIndexedPrimitiveUP
- IDirect3DDevice9::DrawPrimitive
- IDirect3DDevice9::DrawPrimitiveUP
- IDirect3DDevice9::DrawRectPatch
- IDirect3DDevice9::DrawTriPatch
- IDirect3DDevice9::StretchRect
- IDirect3DDevice9::UpdateSurface
- IDirect3DSurface9::GetDC
- IDirect3DSurface9::LockRect
まず出力先がレンダーターゲット固定か,引数に出力先サーフェイスをとるかで分類しよう.次に描画方法について描画コマンド系とLock系という分類が可能である.最後に描画領域指定の仕方で分類を行うと,頂点位置を直接指定するか座標軸に平行な辺を持つ矩形を指定するかの違いがある.これらをまとめたのが以下の表である.
Method Name | Destination | Render Type | Region Control |
---|---|---|---|
IDirect3DDevice9::Clear | Render Target | Command | Axis-Aligned Rectangle |
IDirect3DDevice9::ColorFill | Surface | Command | Axis-Aligned Rectangle |
IDirect3DDevice9::DrawIndexedPrimitive | Render Target | Command | Vertex |
IDirect3DDevice9::DrawIndexedPrimitiveUP | Render Target | Command | Vertex |
IDirect3DDevice9::DrawPrimitive | Render Target | Command | Vertex |
IDirect3DDevice9::DrawPrimitiveUP | Render Target | Command | Vertex |
IDirect3DDevice9::DrawRectPatch | Render Target | Command | Vertex |
IDirect3DDevice9::DrawTriPatch | Render Target | Command | Vertex |
IDirect3DDevice9::StretchRect | Surface | Command | Axis-Aligned Rectangle |
IDirect3DDevice9::UpdateSurface | Surface | Command | Axis-Aligned Rectangle |
IDirect3DSurface9::GetDC | Surface | Lock | Axis-Aligned Rectangle |
IDirect3DSurface9::LockRect | Surface | Lock | Axis-Aligned Rectangle |
まず重要なこととして,描画命令として一級市民扱いできるのは出力先がRender Targetな命令のみである.これらの命令は,毎フレームの描画に用いてビデオカードが価格相応の働きをしてくれることが期待できる.この意味で堂々と描画命令を名乗ることができるだろう.また,アルファブレンディングやZテスト,各種プログラマブルシェーダーなどを利用することが出来る*1.
一方出力先がSurface(あるいはTexture)である命令は,サーフェイスに意味のある画像を作り出すことが第一義であって,本来の目的はディスプレイ出力ではない.実際,レンダーターゲットを出力サーフェイスとして引数にとるには様々な制限が存在する.そのためこれらは常に描画に使えるとは限らない.また,アルファブレンディングなどは使用できず,受けられるハードウェアサポートが大幅に制限されている.
描画コマンド系の命令は,描画命令の引数や呼んだ時点でのデバイス設定によってどのような描画が行われるかが確定する.一方,Lock系の命令はドライバが用意したテンポラリバッファを介して画像を引き渡す.Lock系の特徴を挙げるとすれば,「画像の書き込みだけでなく読み出しにも利用できる」,「描画内容はCPU命令によって制御される」という点であろう.かつてはこの様な方法が画面描画の主流だった時代もあった.しかし繰り返すがDirectX9の設計はLockによる描画を「期待していない」.
描画領域の指定方法に関してはデータ設計,あるいは数学的な思想の違いである.これについてはいずれ詳しく述べることにする.
結論として,標語的には「DirectX9の描画命令はIDirect3DDevice9::DrawほにゃららPrimitiveのみ」と考えればよい*2.描画命令が(亜種はあれど)一種類.(これだけ聞くと)美しいまでにシンプル.そしてメーカーさんはIDirect3DDevice9::DrawほにゃららPrimitiveの高速化に血道を上げ,デベロッパーはひたすらにIDirect3DDevice9::DrawほにゃららPrimitiveを呼び続ける.これが描画命令という観点から見たここ数年の出来事である.