トラブルシューティング (Direct3D 9)
ここでは、Direct3D アプリケーションの開発中に発生する可能性がある問題を一般的なカテゴリ別に示し、その回避方法について説明します。
デバイスの作成
デバイスの作成中にアプリケーションが異常終了した場合は、次の共通のエラーを確認してください。
- デバイスの能力、特にレンダリング深度を確認します。
- エラー コードを調べます。常に D3DERR_OUTOFVIDEOMEMORY が考えられます。
- デバッグ Direct3D ダイナミック リンク ライブラリ (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 <math.h>
#include <float.h>
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 Immediate Mode ランタイムのデバッグ バージョンでは、リテール バージョンの場合より多くのパラメーターの検証を行います。リテール バージョンでは、検証がまったく行われないこともあります。これを使用することで、アプリケーションでは低速なデバッグ ランタイム コンポーネントによって安定したデバッギングを実行でき、その後で高速なリテール バージョンを使用してパフォーマンスを調整し、最終的なリリースに備えることができます。
Direct3D Immediate Mode のいくつかのメソッドでは、使用可能な値に制限があるが、この制限は Direct3D Immediate Mode ランタイムのデバッグ バージョンだけがチェックして実施することがよくあります。アプリケーションはこの制限に従う必要があります。これに従っていないと、Direct3D のリテール バージョンで実行したときに、予想外の好ましくない結果が生じる可能性があります。たとえば、IDirect3DDevice9::DrawPrimitive メソッドでは、このメソッドでレンダリングするプリミティブの個数を示すパラメーター (PrimitiveCount) を使います。このメソッドで使用できる値の範囲は 0 ~ D3DMAXNUMPRIMITIVES です。Direct3D のデバッグ バージョンで、D3DMAXNUMPRIMITIVES 個より多くのプリミティブを渡した場合、メソッドは異常終了し、エラー ログにエラー メッセージを出力して、アプリケーションにエラー値を返します。逆に、ランタイムのリテール バージョンで実行している場合にアプリケーションで同じエラーが発生したときは、動作は不定です。パフォーマンス上の理由から、メソッドはパラメーターの検証を行いません。したがって、パラメーターが有効でない場合には、その状況に依存した予想外の動作が生じます。場合によっては、呼び出しが行われることもあります。また、場合によっては、その呼び出しに起因して Direct3D でメモリー障害が発生することもあります。無効な呼び出しが特定のハードウェア構成と DirectX のバージョンで一貫して機能したとしても、他のハードウェアや DirectX の今後のリリースで機能することは保証されません。
リテール Direct3D ランタイム ファイルでアプリケーションを実行している場合に、説明できない障害が発生したときは、デバッグ バージョンに対してテストを行い、アプリケーションで無効なパラメーターを渡している箇所がないかどうかを慎重に調べる必要があります。DirectX コントロール パネル アプレットを使って必要な場合はデバッグ ランタイムに切り替え、[Break on D3DError] オプションをオンにします。このオプションにより、アプリケーションのバグを検出したときにアプリケーションを強制的に停止するために、ランタイムは Windows DebugBreak メソッドを使います。