GameComponent サンプル

ここのところ XNA 関係で訪問してくださっている方が多いようなので,少し XNA ネタでも.
ひげねこさんのところで紹介されていたゲーム・コンポーネントについて.
http://higeneko.com/diary.php?Date=2006-09-01#Date2006-09-01
詳細についてはひげねこさんのページを参照していただくとして,ちょっとしたサンプルを作ってみたので公開してみます.

背景事情

デバッグ版の DirectX のランタイムライブラリは,非常に丁寧にパラメータ検証を行ってくれて,何か問題があるとその詳細について OutputDebugString API 経由で出力してくれます.しかし,Managed DirectX 開発などのマネージコードのみのデバッグ時には,Visual Studio は OutputDebugString 出力をモニタリングしてくれないという問題がありました.これに対する解決策としては次のようなものがあります.

  1. プロジェクトのデバッグ設定から,「アンマネージ コード デバッグ」を有効にする (Visual C# 2005 Express Edition では使用不可)
  2. DebugView や DbMon などの,ネイティブのデバッグメッセージモニタを併用する.

前者はデバッグ作業がかなり重くなってしまうので,個人的には後者がおすすめです.

デバッグメッセージ リダイレクト用 GameComponent : DTrace

上に挙げたデバッグメッセージの問題は XNA についても同様です.そこで,今回は追加するだけでデバッグメッセージを System.Diagnostics.Trace.WriteLine にリダイレクトしてくれる*1ようになる,お手軽な GameComponent を作成してみました.
http://www.dwahan.net/nyaruru/hatena/DTrace.zip
(ソース付き.コンパイルには Visual C++ 2005 が必要)
原理はいつも通りで,CodeZine の記事 (id:NyaRuRu:20051220#p2) で作成・紹介した API フックライブラリを使用して,d3d9d.dll の OutputDebugStringA API 呼出しをフックしているだけです.本当は d3dx9d_30.dll あたりにもフックを仕掛けるべきなのでしょうが,そのあたりは皆さんへの宿題ということで.

使用方法

簡単に使用方法について紹介しておきましょう.
まずDirectX Control Panelユーティリティから,デバッグランタイムの設定を行っておきます.Microsoft DirectX SDK (August 2006) からは,インストール場所が変わっているので注意.形式が exe ファイルに変更され,DirectX SDK の他のユーティリティと同じ場所にインストールされるようになっています.

次に,Visual C# 2005にて,メニューの「ツール」→「ツールボックス アイテムの選択」を選びます.

ここで,ダウンロードした DTrace.dll を追加します.

これでツールボックスに DTarace という項目が追加されるはずです.
後は,XNA のプロジェクトを開き,デザイナの表示にて DTrace をドラッグアンドドロップすれば作業は完了です.

実際に動いているかどうか試してみましょう.
EndScene メソッドの呼出しを意図的にコメントアウトすると次の Present メソッドで例外が発生しますが,以下このときの出力ペインの内容です.

実際に,デバッグランタイムがエラーの原因についてずばり教えてくれているのが分かるかと思います.

Trace クラスについて

.NET では,Trace クラスの出力先を柔軟にカスタマイズできるので,ファイルに出力したり,設定ファイルによって出力先を変えたりすることができます.詳細については以下の記事などが参考になるでしょう.
.NETでのトレースの方法と独自のトレースリスナの実装

*1:本当は System.Diagnostics.Trace.Write の方がいいのかも