効果をコンパイルする (Direct3D 11)
効果が作成されたら、次の手順では、コードをコンパイルして構文の問題をチェックします。
これを行うには、コンパイル API (D3DX11CompileFromFile、 D3DX11CompileFromMemory、または D3DX11CompileFromResource ) のいずれかを呼び出します。 これらの API は、HLSL コードをコンパイルするエフェクト コンパイラ fxc.exeを呼び出します。 このため、エフェクト内のコードの構文は HLSL コードによく似ています。 (後で処理される例外がいくつかあります)。 エフェクト コンパイラ/hlsl コンパイラ (fxc.exe) は、選択した場合にシェーダー (または効果) をオフラインでコンパイルできるように、ユーティリティ フォルダーの SDK で使用できます。 コマンド ラインからコンパイラを実行する方法については、ドキュメントを参照してください。
例
効果ファイルをコンパイルする例を次に示します。
WCHAR str[MAX_PATH];
DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX11CompileFromFile( str, NULL, NULL, pFunctionName, pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL, NULL, &pBlob, &pErrorBlob, NULL );
Includes
コンパイル API のパラメーターの 1 つはインクルード インターフェイスです。 コンパイラがインクルード ファイルを読み取るときにカスタマイズされた動作を含める場合は、次のいずれかを生成します。 コンパイラは、(インクルード ポインターを使用する) 効果を作成またはコンパイルするたびに、このカスタム動作を実行します。 カスタマイズされたインクルード動作を実装するには、 ID3DInclude インターフェイスからクラスを派生させます。 これにより、クラスに Open メソッドと Close メソッドの 2 つのメソッドが提供されます。 これらのメソッドでカスタム動作を実装します。
インクルード ファイルの検索
コンパイラが pParentData パラメーターをインクルード ハンドラーの Open メソッドに渡すポインターは、コンパイラがシェーダー コードをコンパイルするために必要な#include ファイルを含むコンテナーを指していない可能性があります。 つまり、コンパイラは pParentData で NULL を渡す可能性があります。 そのため、インクルード ハンドラーでコンテンツのインクルードの場所の独自のリストを検索することをお勧めします。 インクルード ハンドラーは、 Open メソッドの呼び出しでこれらの場所を受信すると、新しいインクルードの場所を動的に追加できます。
次の例では、シェーダー コードのインクルード ファイルが両方とも somewhereelse ディレクトリに格納されているとします。 コンパイラがインクルード ハンドラーの Open メソッドを呼び出して somewhereelse\foo.h の内容を開いて読み取ると、インクルード ハンドラーは somewhereelse ディレクトリの場所を保存できます。 その後、コンパイラが include ハンドラーの Open メソッドを呼び出して bar.h の内容を開いて読み取ると、include ハンドラーは bar.h のどこかにあるディレクトリで自動的に検索できます。
Main.hlsl:
#include "somewhereelse\foo.h"
Foo.h:
#include "bar.h"
マクロ
効果のコンパイルでは、他の場所で定義されているマクロへのポインターを取得することもできます。 たとえば、BasicHLSL10 の効果を変更して、0 と 1 の 2 つのマクロを使用するとします。 2 つのマクロを使用する効果コードを次に示します。
if( bAnimate )
vAnimatedPos += float4(vNormal, zero) *
(sin(g_fTime+5.5)+0.5)*5;
Output.Diffuse.a = one;
2 つのマクロの宣言を次に示します。
D3D10_SHADER_MACRO Shader_Macros[3] = { "zero", "0", "one", "1.0f", NULL, NULL };
マクロは NULL で終わるマクロの配列です。ここで、各マクロは 、D3D10_SHADER_MACRO 構造体を使用して定義されます。
マクロへのポインターを取得するようにコンパイル効果の呼び出しを変更します。
D3DX11CompileFromFile( str, Shader_Macros, NULL, pFunctionName,
pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL,
NULL, &pBlob, &pErrorBlob, NULL );
HLSL シェーダー フラグ
シェーダー フラグは、HLSL コンパイラに対するシェーダー制約を指定します。 これらのフラグは、シェーダー コンパイラによって生成されるコードに次の方法で影響します。
- コード サイズを最適化します。
- フロー制御を妨げるデバッグ情報を含めます。
- コンパイル ターゲットと、シェーダーをレガシ ハードウェアで実行できるかどうかを影響します。
競合する 2 つの特性を指定していない場合は、これらのフラグを論理的に組み合わせることができます。 フラグの一覧については、「 D3D10_SHADER定数」を参照してください。
FX フラグ
これらのフラグは、コンパイル動作またはランタイム効果の動作を定義する効果を作成するときに使用します。 フラグの一覧については、「 D3D10_EFFECT定数」を参照してください。
エラーのチェック
コンパイル中にエラーが発生した場合、API はエフェクト コンパイラからエラーを含むインターフェイスを返します。 このインターフェイスは ID3DBlob と呼ばれます。 直接読み取り可能ではありません。ただし、データ (文字列) を含むバッファーへのポインターを返すことで、コンパイル エラーを確認できます。
この例では、BasicHLSL.fx にエラーが含まれています。最初の変数宣言は 2 回発生します。
//-------------------------------------------------------------------
// Global variables
//-------------------------------------------------------------------
float4 g_MaterialAmbientColor; // Material's ambient color
// Declare the same variable twice
float4 g_MaterialAmbientColor; // Material's ambient color
このエラーにより、Microsoft Visual Studio の [ウォッチ] ウィンドウの次のスクリーン ショットに示すように、コンパイラは次のエラーを返します。
コンパイラは LPVOID ポインターでエラーを返すので、ウォッチ ウィンドウの文字列にキャストします。
失敗したコンパイルからエラーを返すコードを次に示します。
// Read the D3DX effect file
WCHAR str[MAX_PATH];
ID3DBlob* l_pBlob_Effect = NULL;
ID3DBlob* l_pBlob_Errors = NULL;
hr = DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX11CompileFromFile( str, NULL, NULL, pFunctionName,
pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL,
NULL, &pBlob, &pErrorBlob, NULL );
LPVOID l_pError = NULL;
if( pErrorBlob )
{
l_pError = pErrorBlob->GetBufferPointer();
// then cast to a char* to see it in the locals window
}
関連トピック