効果をコンパイルする (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 );
含む
コンパイル API のパラメーターの 1 つはインクルード インターフェイスです。 コンパイラがインクルード ファイルを読み取るときにカスタマイズされた動作を含める場合は、次のいずれかを生成します。 コンパイラは、(インクルード ポインターを使用する) 効果を作成またはコンパイルするたびに、このカスタム動作を実行します。 カスタマイズされたインクルード動作を実装するには、ID3DInclude インターフェイスからクラスを派生させます。 これにより、クラスには、Open と Closeの 2 つのメソッドが用意されています。 これらのメソッドでカスタム動作を実装します。
インクルード ファイルの検索
コンパイラが pParentData パラメーターでインクルード ハンドラーの Open メソッドに渡すポインターは、コンパイラがシェーダー コードをコンパイルするために必要な #include ファイルを含むコンテナーを指していない可能性があります。 つまり、コンパイラは pParentData null渡す場合があります。 そのため、インクルード ハンドラーがコンテンツのインクルードの場所の独自のリストを検索することをお勧めします。 インクルード ハンドラーは、Open メソッドの呼び出しでそれらの場所を受け取ると、新しいインクルードの場所を動的に追加できます。
次の例では、シェーダー コードのインクルード ファイルが両方とも ディレクトリに格納されているとします。 コンパイラがインクルード ハンドラーの Open メソッドを呼び出して、whereelse\foo.hの内容を開いて読み取ると、インクルード ハンドラーは の場所をどこかの場所 ディレクトリに保存できます。 その後、コンパイラがインクルード ハンドラーの 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 のウォッチ ウィンドウの次のスクリーン ショットに示すように、コンパイラは次のエラーを返します。
0x01997fb8 エラースクリーン ショット
コンパイラは 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
}
関連トピック