連載
.NET&Windows Vistaへ広がるDirectXの世界

第4回 XNA Game Studio Expressを触ってみよう!

NyaRuRu
Microsoft MVP Windows - DirectX(Jan 2004 - Dec 2006)
2006/11/01
Page1 Page2 Page3 Page4

【コラム】DirectX SDKのインストールとデバッグへの応用

 Windows環境のMDX/XNAアプリケーションには、当然のことながらWin32アプリケーションに対する既存のデバッグ・プロファイリング手法が適用可能である。ここではDirectXにおけるデバッグ手法について紹介しておこう。XACTツールを使用しなければXNA開発には必ずしもDirectX SDKは必須ではないが、デバッグ目的のためだけでもDirectX SDKはインストールする価値がある。

 最新のDirectX SDKは「Microsoft DirectX 9.0 ダウンロード」からダウンロードできる。この記事を書いている時点で最新のSDKは「DirectX 9.0 SDK October 2006」であるが、恐らく今後もアップデートが行われていくであろうことから、最新情報については常にリリース・ノートを参照するようにしていただきたい。ただし、リリース・ノートには基本的に前回のSDKとの差分と既知の問題点しか書かれないので、場合によっては以前のリリース・ノートも参照する必要があるかもしれない。

 さて、DirectX SDKを利用したデバッグ・テクニックについて見てみよう。

 Direct3Dアプリケーションのデバッグは難しいが、それにはいくつか理由がある。例えばDirect3DのDeviceオブジェクトが巨大なステート・マシンであるため、正しく動作するには正確にそのステートを設定しなければならないのだが、エラー・コードがE_INVALIDARGだったからといってどのパラメータに問題があるのかすぐには分からないことが多い。

 またパフォーマンス上の理由から、DirectXランタイムは実行時のパラメータ検証を極力省略しており、戻り値は成功を返していても表示が乱れたりまったく表示されなかったりといったこともある。MDXやXNAの実行時例外を見てもいまひとつ原因がつかみにくいのは、そもそもネイティブDirect3Dの段階で得られるエラー情報が非常に限られたものであるからなのだ。

XNAアプリケーションのデバッグ中に表示されるエラー・ダイアログの例
Windows Game (XNA)テンプレートで生成されるプロジェクトで、Game1.Draw()メソッド内のgraphicsComponent1.GraphicsDevice.EndScene()をコメントアウトしたときに発生するエラーである。
Direct3D 9では、IDirect3DDevice9::BeginScene→描画処理→IDirect3DDevice9::EndScene→IDirect3DDevice9::Presentという順でメソッドを呼び出さなければならないが、このEndSceneメソッドをコメントアウトしたためにPresentメソッドでエラーが発生している。
このときの戻り値はD3DERR_INVALIDCALLという一般的なものであるため、それをラップしたInvalidCallException例外にはそれ以上詳しい情報を持たせることができないのだ。この例外だけを見て、EndSceneメソッドが呼ばれていないという原因を見抜くのは難しい。

 このようなトラブルの解決に役立つのがDirect3Dデバッグ・ランタイムだ。DirectXランタイムには、エンド・ユーザー向けのリテール版と、開発者がデバッグ時に使用するためのデバッグ版が存在する。

 デバッグ版ランタイムは、開発者向けに公開されているパラメータ検証を強化したランタイム・ライブラリで、エラーの原因や注意事項をWin32 APIであるOutputDebugString関数を使用して出力してくれる。デバッグ版ランタイム使用時には若干パフォーマンスが低下するものの、ロジックのミスを発見する場合には非常に強力な武器となる。

 デバッグ版ランタイムは、DirectX SDKをインストールすることで入手でき、設定によって再起動なしに切り替え可能である。

DirectXのプロパティ
従来はコントロール・パネルにインストールされていたが、DirectX SDK August 2006からは.exeファイル形式のユーティリティに変更された。今後D3D10時代にはさらに変更が行われる可能性があるが、このようなデバッグ支援機能を活用してデバッグを効率化するという構図は変わらないだろう。
  [Debug Output Level]はデバッグ・メッセージの出力レベルを変更する。「More」に行くほどより細かいメッセージが表示されるようになる。
  [Debug/Retail D3D Runtime]は、使用するランタイムの種類を選択する。プログラム実行に(正確にはDeviceオブジェクトを生成した時点で)選択されているライブラリが読み込まれる。
  [Debugging]は、そのほかのチェック項目について選択する(詳細割愛)。

 ただし、OutputDebugString関数はいわゆるネイティブ・アプリケーションのデバッグ機能であるため、そのままではVC# Expressの出力ペインに表示されない。

 上位エディションであれば、プロジェクト・プロパティの設定から[デバッグ]タブを開き、[アンマネージ コード デバッグを有効にする]というチェックボックスにチェックを入れることで出力されるようになるが、残念ながらVC# Expressではこの設定は利用できない。

 次の画面はVC# Expressの設定項目だが、このように限られた設定しかできないようになっている。

VC# Expresssでのプロジェクト設定
限られた設定しかできないようになっている。

 一方、上位エディションのVisual Studioでは、次の画面のように[アンマネージ コード デバッグを有効にする]というチェックボックスが存在する。

Visual C# 2005上位エディションでのプロジェクト設定
ここで[アンマネージ コード デバッグを有効にする]チェックボックスにチェックを入れることで、アンマネージ・コードのデバッグ・メッセージが表示されるようになる。

 このように[アンマネージ コード デバッグを有効にする]はすべてのエディションで使用できるわけではなく、また使用できる環境でもデバッグ実行時の起動時間・処理速度が大幅に低下してしまうという副作用がある。

 しかし実は、単にアンマネージのデバッグ・メッセージを見るだけであればもっと簡単な方法がある。それは、Platform SDK(今後は.NET Framework SDKに統合され、Windows SDKとなる予定)に付属する「Debug Monitor」(dbmon.exe)や、Sysinternals社から公開されている「DebugView」といった、専用のツールを使用してデバッグ・メッセージを表示させる方法だ。

 これらのツールは、起動しておくだけでデバッグ・メッセージを表示してくれる。

Platform SDKに付属のDebug Monitorによるデバッグ・メッセージのモニタリング
先ほどのPresentメソッドのエラー時に表示されたデバッグ・メッセージ。エラーの原因がメッセージとして表示されている。さまざまなバグと戦ううえで、非常に頼りになる存在だ。

 MDXやXNAで初めてDirectXに手を出すと、思いのほかデバッグに苦労して、ネイティブDirectXの開発者は毎回こんな難しいデバッグをしているのかと思われることがあるかもしれない。もちろんネイティブDirectXの開発でもデバッグは大変なのだが、大変なりにツールやテクニックを利用して効率よくデバッグをしているのである。

 いわゆる慣れた開発者は、「PresentメソッドがInvalidCallException例外をスローしたらEndSceneメソッドの呼び忘れを疑う」といった個々の事例を逐一暗記しているのではなく(とはいえ似たようなトラブルに何度も出合うとだんだんと直感が働くようになってくるのは確かだが)、どんなトラブルでも確実に原因を絞り込むためのノウハウを持っているということだ。

 これはDirectX開発に限らず、ほぼすべてのプログラミングに通用する重要なポイントである。もしあなたがDirectX開発で初めてプログラミングに接することになったというのであれば、DirectXでそれを学ぶことになるだろうし、他分野でデバッグ・テクニックの重要性について学ばれているのであれば、DirectX開発特有のデバッグ・テクニックを知っておくことの重要性を十分にご理解いただけるだろう。

 もしこういったデバッグ・テクニック全般に興味を持たれたのなら、『.NET & Windowsプログラマのためのデバッグテクニック徹底解説』という名著がある。やや高価な本だが、未読の方にはぜひお勧めしたい。

 最後にもう1つだけ有用なツールを紹介しておこう。

 最近のDirectX SDKには「PIX for Windows」という非常に強力な解析ツールが付属している。PIXはもともとXbox用に開発されていたツールで、それが非常に便利ということでWindowsのDirectX開発にも使用できるように移植されたのがこのPIX for Windowsである。

 紙面の都合で詳細については紹介できないが、XNAアプリケーションの解析にももちろん使用可能である。下の画像は、実際にXNA付属のサンプル・ゲームをPIXで解析しているものだ。

PIX for Windowsによるサンプル・ゲーム「Spacewar」の解析
  Timelineウィンドウ。さまざまなパラメータをグラフ表示するのに使用する。
  Objectsウィンドウ。Direct3Dに関連するオブジェクトについて、メモリ上のアドレスやCOMの参照カウント、使用メモリ量などが表示される。表示内容はExcelのように特定項目でソートしたり絞り込みをしたりすることができる。
  Eventsウィンドウ。すべてのDirect3D API呼び出しとD3DX API呼び出しを時系列順に並べ、API呼び出し時のパラメータの内容などを調べることができる。
  このウィンドウはタブによって複数の用途に使用される。Renderウィンドウは指定された時点の描画結果を表示するのに使用する。このウィンドウでは、指定されたオブジェクトのステートを一覧表示したり、頂点バッファの内容をダンプしたり、プログラマブル・シェーダのデバッグを行ったりすることもできる。

 もちろん、ここで紹介したデバッグ・テクニックは、MDX開発でも有効である。

 

 INDEX
  .NET&Windows Vistaへ広がるDirectXの世界
  第4回 XNA Game Studio Expressを触ってみよう!
    1.XNA Game Studio Expressベータ版のインストール
  2.【コラム】DirectX SDKのインストールとデバッグへの応用
    3.XNA Game Studio Expressベータ版を使ってみよう
    4.【コラム】VC# Expressで出力アセンブリのプラットフォームを設定する
 
インデックス・ページヘ  「.NET&Windows Vistaへ広がるDirectXの世界」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間