トラブルシューティング
トラブルシューティング
ここでは、Microsoft® Direct3D® アプリケーションの開発中に発生する可能性がある問題を一般的なカテゴリ別に示し、その回避方法について説明する。
デバイスの作成
デバイスの作成中にアプリケーションが異常終了した場合、次の共通のエラーを調べる。
- デバイス能力、特にレンダリング深度を調べる。
- エラー コードを調べる。常に D3DERR_OUTOFVIDEOMEMORY が考えられる。
- デバッグ Microsoft DirectX® ダイナミック リンク ライブラリ (DLL) を使って、デバッガに表示される出力メッセージを確認する。
ライティング済み頂点の使い方
ライティング済み頂点を使用するアプリケーションの場合、D3DRS_LIGHTING レンダリング ステートを FALSE に設定して、Direct3D ライティング エンジンを無効にする必要がある。デフォルトでは、ライティングは有効になっており、入力頂点にゼロ以外の色値が含まれていても、システムは法線ベクトルを含んでいない頂点の色を 0 (黒) に設定する。本来、ライティング済み頂点には頂点法線が含まれないので、ライティング エンジンが有効になっていると、Direct3D に渡される色情報はレンダリングの際にすべて失われる。
独自のラインティングを実行するアプリケーションにとって、頂点色が重要であることは言うまでもない。システムによるデフォルト値の使用を回避するために、D3DRS_LIGHTING を FALSE に設定すること。
アプリケーションを実行しても何も表示されない場合、次の共通のエラーを調べる。
- 三角形がなくなっていないことを確認する。
- 三角形がカリングされていないことを確認する。
- トランスフォームが内部的に一貫していることを確認する。
- ビューポートの設定を調べて、三角形の表示が可能になっていることを確認する。
デバッグ
Direct3D アプリケーションのデバッグは困難を伴うことがある。すべての戻り値 (Direct3D プログラミングにおいて特に重要な要素であるが、ハードウェアの実装によって大きく異なる) を調べるほか、次の手法を試してみる。
- デバッグ DLL に切り替える。
- ソフトウェア専用デバイスを強制的に使用し、ハードウェア アクセラレーションが使用可能であってもオフにする。
- サーフェイスを強制的にシステム メモリに配置する。
- ウィンドウで実行するオプションを作成して、統合デバッガを使えるようにする。
Win16 ロックによってデバッガがハングする場合があるが、この一覧の 2 つ目と 3 つ目のオプションは、Win16 ロックを防止する。
また、次のエントリを Win.ini に追加してみる。
[Direct3D]
debug=3
[DirectDraw]
debug=3
ボーランド浮動小数点初期化
ボーランドのコンパイラは、Direct3D との互換性がない方法で浮動小数点例外を報告する。この問題を解決するには、次に示すように、_matherr 例外ハンドラを含める。
// Borland floating point initialization #include #include void initfp(void) { // Disable floating point exceptions. _control87(MCW_EM,MCW_EM); } int _matherr(struct _exception *e) { e; // Dummy reference to catch the warning. return 1; // Error has been handled. }
パラメータの妥当性検査
パフォーマンス上の理由から、Direct3D ランタイムのデバッグ バージョンでは、リテール バージョンの場合より多くのパラメータの妥当性検査を行う。リテール バージョンでは、妥当性検査がまったく行われないこともある。これを使用することで、アプリケーションでは低速なデバッグ ランタイム コンポーネントによって安定したデバッギングを実行でき、その後で高速なリテール バージョンを使用してパフォーマンスを調整し、最終的なリリースに備えることができる。
Direct3D のいくつかのメソッドでは、使用可能な値に制限があるが、この制限は Direct3D ランタイムのデバッグ バージョンだけがチェックして実施することが多い。アプリケーションはこの制限に従う必要がある。これに従っていないと、Direct3D のリテール バージョンで実行したときに、予想外の好ましくない結果が生じる可能性がある。たとえば、IDirect3DDevice9::DrawPrimitive メソッドでは、このメソッドでレンダリングするプリミティブの個数を示すパラメータ (PrimitiveCount) を使う。 このメソッドで使用できる値の範囲は 0 ~ D3DMAXNUMPRIMITIVES である。Direct3D のデバッグ バージョンで、D3DMAXNUMPRIMITIVES 個より多くのプリミティブを渡した場合、メソッドは異常終了し、エラー ログにエラー メッセージを出力して、アプリケーションにエラー値を返す。逆に、ランタイムのリテール バージョンで実行している場合にアプリケーションで同じエラーが発生したときは、動作は不定である。パフォーマンス上の理由から、メソッドはパラメータの妥当性検査を行わない。したがって、パラメータが有効でない場合には、その状況に依存した予想外の動作が生じる。場合によっては、呼び出しが行われることもある。また、場合によっては、その呼び出しに起因して Direct3D でメモリ障害が発生することもある。無効な呼び出しが特定のハードウェア構成と DirectX のバージョンで一貫して機能したとしても、他のハードウェアや DirectX の今後のリリースで機能することは保証されない。
リテール Direct3D ランタイム ファイルでアプリケーションを実行している場合に、説明できない障害が発生したときは、デバッグ バージョンに対してテストを行い、アプリケーションで無効なパラメータを渡している箇所がないかどうかを慎重に調べること。DirectX コントロール パネル アプレットを使って必要な場合はデバッグ ランタイムに切り替え、[Break on D3DError] オプションをオンにする。このオプションにより、アプリケーションのバグを検出したときにアプリケーションを強制的に停止するために、ランタイムは Windows DebugBreak メソッドを使う。