DXUT によるエラー処理
Direct3D API は、エラーを簡単に処理できるように設計されています。ほとんどの Direct3D API では、成功または失敗を確認できる HRESULT が返されます。最も一般的な失敗の HRESULT は D3DERR_INVALIDCALL であり、メソッドが間違った入力パラメーターに渡されたときに返されます。
開発の際には、アプリケーションで、すべての Direct3D API の呼び出しの失敗をチェックして、結果をログに記録する必要があります。失敗のログを収集することにより、開発者が、間違って呼び出された API 関数を簡単にデバッグできるようになります。開発後の成熟したアプリケーションでは、IDirect3DDevice9::Present や IDirect3DDevice9::TestCooperativeLevel などのいくつかの重要な関数を除く、Direct3D API のほとんどのエラーは無視しても問題ありません。運用コードで HRESULTS を無視することにより、速度が向上し、コード パスの単純化によってコードがより堅牢になります。
- エラー メッセージ
- 例
エラー メッセージ
DXUT でのエラー処理は、Direct3D API でのエラー処理と非常によく似ています。重大なエラー (メディアの不足など) が発生すると、ユーザーへ通知され、アプリケーションが終了されます。フレームごとの関数で比較的軽度なエラーがあると、デバッグ ビルドでダイアログ ボックスが表示されます。これらのエラーは、リテール ビルドでは無視されます。
DXUT では、DxStdAfx.h で複数のマクロを定義することにより、これが実現されています。
#if defined(DEBUG) | defined(_DEBUG)
#define V(x)
{
hr = x;
if( FAILED(hr) )
{
DXUTTrace( __FILE__, (DWORD)__LINE__, hr, L#x, TRUE );
}
}
#define V_RETURN(x)
{
hr = x;
if( FAILED(hr) )
{
return DXUTTrace( __FILE__, (DWORD)__LINE__, hr, L#x, TRUE );
}
}
#else
#define V(x)
{
hr = x;
{
#define V_RETURN(x)
{
hr = x;
if( FAILED(hr) )
{
return hr;
}
}
#endif
例
次に、V マクロの使用例をいくつか示します。
V( g_pEffect->BeginPass( iPass ) );
V( g_pEffect->CommitChanges() );
V( g_pMesh->DrawSubset( 0 ) );
コンパイラーのデバッグ出力は、次のようになります。
c:\basichlsl\basichlsl.cpp(242):
D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial",
NULL ) hr=D3DERR_INVALIDCALL (0x8876086c)
Visual Studio では、デバッグ出力ウィンドウでこの行 (242) をダブルクリックすることによって、ソース コードへジャンプできます。
次に、V_RETURN マクロの使用例を示します。
V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str,
NULL, NULL, dwShaderFlags,
NULL, &g_pEffect, NULL ) );
このマクロでは、全てのビルドに対して同じダイアログ ボックスが表示され、失敗した HRESULT が呼び出し元の関数へ返されます。
DXUT のエラー処理のその他の例については、「Direct3D 9 のチュートリアルとサンプル」を参照してください。
マクロ間の違い
利用可能なマクロには、次の 2 つがあります。
マクロ | ダイアログ ボックス | 呼び出し元へ返される HR 値 |
---|---|---|
V | デバッグとリリース | × |
V_RETURN | デバッグのみ | ○ |
DXUT でエラー メッセージ ボックスの表示を無効にするには、次のいずれかを行います。
DXUTInit を呼び出す
コマンド ラインからアプリケーションを実行するときに、コマンド ライン引数
-noerrormsgboxes
を使用する