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を呼び続ける.これが描画命令という観点から見たここ数年の出来事である.

*1:ただしIDirect3DDevice9::Clearではサポートされない.性質上当然といえば当然であるが

*2:もちろんClearだけでもゲームを作ることは出来る.というかむしろ宿題.DrawほにゃららPatchはnVIDIAがノってこないので事実上封印状態