XNA Game Studio 4.0、グラフィクスAPI・リファクタリング
XNA Frameworkの歴史
XNAチームは発足当初から他のMicrosoftのプロダクトチームに比べると非常に少ない人数です。人数的に見て他のチームがXNAチームの10倍の規模なんていうのは普通にあることで、時には100倍の人数規模のチームと仕事をするなんてこともあります。
私達がXNA Game Studio 1.0の時にFrameworkを設計したときにはXbox 360上で.Net CFを動くようになったのは最初のリリースの四ケ月程前でした。もちろん、たった四ケ月という期間と少ない人員でFrameworkの設計、実装、そしてテストをすることはできないので、Xbox 360上で.Net CFが動くまでの間に平行して他の作業を進めました。
この時点で私達が設計、実装ができたのはWindows上のみだったので、自然とManaged DirectXの設計を参考にする機会が多くなり、どちらかというとDirectX 9.0のラッパーのようなものが多くなりました。
この方針は設計期間を短くすることに繋がったのですが、後になってXbox 360とWindows上の動作に違い、例えばRenderTarget2Dの振る舞いの違いなどがあることに気づいた時には既にAPIの仕様を変更するには遅すぎる時期になってしまい、結局はXbox 360とWindowsの動作の違いはそのままにすることになってしまいました。
また、追加してしまつた機能を削除するのは、新しく機能を追加するよりも遥かに難しいということを実感したのもXNA Game Studio Express 1.0をリリースした後になってからでした。
一度追加してしまった機能は、使用頻度が少なくとも削ってしまうと、それまで動作していたゲームが動かないということになってしまいます。この使用頻度が低いAPIというのが厄介で、いかに使用頻度が低くてもAPIとして提供している以上はそのAPIが動作しているかどうか確認するためのテストをする必要があります。そして、前述のように人員の少ないXNAチームでは、このテストに掛かる時間が多くなってしまい、そのことで新機能を追加する時間が少なくなってしまうというのは問題です。
将来を見越したリファクタリング
XNA Game Studio 4.0でWindows Phone 7シリーズへの対応が決まった時、私達はこれがリファクタリングをするにはいい機会だと考えました。
特にグラフィクスに関しては今までスマートフォーン向けのGPU用のDirectXドライバは存在せず、ドライバの設計はもちろん、ハードウェアベンダーとの話し合いからすることができた(しなければいけなかった)ので、XNAチーム側からの意見の多くが採用されました。
ここで私達は今まで経験から、できるだけ長い間使えるAPIになるようにDirectX10 APIを元にしたAPIへとリファクタリングをすることにしました。と、言うと「ジオメトリシェーダーが使える!」と、考える人がいると思いますが、残念ですがXNA Game Studio 4.0の段階でDirectX 10特有の機能はサポートしていません。
XNA Game Studio 4.0ではDirectX 9世代のGPUもサポートしているので、DirectX 10 APIをDirectX 9世代のGPU上で使用する、D3D10Level9と同等のことをしています。
XNA Game Studio 4.0のグラフィクスではこの他にも以下のようなリファクタリングが施されています。
- Capsメカニズムの廃止、Reach、HiDefのシンプルなフィーチャーレベルの採用
- RenderStateを廃止し、BlendState、SampleState、DepthStencilState、そしてRasterizerStateとして分別
- RenderTarget2DをTexture2Dから派生したクラスにし、深度バッファとの統合
- アルファテスト関連のステートの廃止(代わりにAlpheTestEffectを使用)
- トライアングルファン・プリミティブの廃止
- ポイント・スプライトの廃止
- VertexShader、PixelShaderなどの低レベルシェーダーAPIの廃止
- BGRAフォーマットの廃止(Color構造体のバイトの並びがRGBAになった)
- EffectPool、StateBlock、GammaRamp、ClipPlaneの廃止
次回は新しくなったレンダーステートの紹介をします。