共用方式為


編譯效果 (Direct3D 10)

撰寫效果之後,第一個步驟是編譯程式代碼以檢查語法問題。 這是藉由呼叫其中一個編譯 API 來完成(例如 D3DX10CompileEffectFromFile、D3DX10CompileEffectFromResource、D3DX10CompileEffectFromMemory)。 這些 API 會叫用效果編譯程式 fxc.exe,這是用來編譯 HLSL 程式代碼的編譯程式。 這就是為什麼效果中的程式代碼語法看起來非常類似 HLSL 程式代碼(稍後會處理一些例外狀況)。 順便說一下,效果編譯程式/hlsl 編譯程式 (fxc.exe) 位於 utilities 資料夾中的 SDK 中,因此,如果您選擇的話,您可以脫機編譯著色器(或效果)。 請參閱從命令行執行編譯程式的檔。

以下是編譯效果檔案的範例(來自 BasicHLSL10 範例)。

WCHAR str[MAX_PATH];
DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );

hr = D3DX10CompileEffectFromFile( str, NULL, NULL, "fx_4_0", 
    D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, NULL, 
    &l_pBlob_Effect, &l_pBlob_Errors, NULL );

包括

一個參數是 include 介面。 如果您想要在讀取 Include 檔案時包含自訂行為,請產生其中一個。 每次建立效果(使用 include 指標)或編譯使用 include 指標的效果時,都會執行這個自定義行為。 若要實作自定義的 Include 行為,請從 Include 介面衍生類別。 這會提供您的類別兩種方法:Open 和 Close。 在Open和 Close 方法中實作自訂行為。

巨集

效果編譯也可以取得其他位置所定義的巨集指標。 例如,假設您要修改 BasicHLSL10 中的效果,以使用兩個巨集:零和一個。 使用兩個巨集的效果程序代碼如下所示。

if( bAnimate )
    vAnimatedPos += float4(vNormal, zero) *  
        (sin(g_fTime+5.5)+0.5)*5;
        
    Output.Diffuse.a = one;         

以下是兩個巨集的宣告。

D3D_SHADER_MACRO Shader_Macros[3] = { "zero", "0", "one", "1.0f", NULL, NULL };

巨集是 NULL 終止的巨集陣列;其中每個巨集都是使用 D3D_SHADER_MACRO 結構來定義。

最後,修改編譯效果呼叫,以取得巨集的指標。

D3DX10CreateEffectFromFile( str, Shader_Macros, NULL, 
    D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, NULL, 
    &g_pEffect10, NULL );

HLSL 著色器旗標

著色器旗標會指定 HLSL 編譯程式的著色器條件約束。 這些旗標會影響著色器編譯程式所產生的程序代碼,包括:

  • 大小考慮:優化程序代碼。
  • 偵錯考慮:包括偵錯資訊、防止流程控制。
  • 硬體考慮:編譯目標,以及著色器是否可以在舊版硬體上執行。

一般而言,這些旗標可以邏輯方式結合,假設您未指定兩個衝突的特性。 如需旗標的清單,請參閱 效果常數 (Direct3D 10)

FX 旗標

建立效果以定義編譯行為或運行時間效果行為時所使用的這些旗標。 如需旗標的清單,請參閱 效果常數 (Direct3D 10)

檢查錯誤

如果在編譯期間發生錯誤,API 會傳回介面,其中包含從效果編譯程式傳回的錯誤。 這個介面稱為ID3D10Blob。 不過,它無法直接讀取,方法是傳回包含數據之緩衝區的指標(也就是字串),您可以看到任何編譯錯誤。

在此範例中,藉由複製第一個變數宣告兩次,將錯誤引入 BasicHLSL.fx 效果中。

//-------------------------------------------------------------------
// Global variables
//-------------------------------------------------------------------
float4 g_MaterialAmbientColor;      // Material's ambient color

// Declare the same variable twice
float4 g_MaterialAmbientColor;      // Material's ambient color

此錯誤導致編譯程式傳回下列錯誤,如 Visual Studio 中監看式視窗 Microsoft的下列螢幕快照所示。

visual Studio監看式視窗的螢幕快照

由於錯誤會在 LPVOID 指標中傳回,所以將其轉換成監看式視窗中的字元字串。

以下是用來從失敗編譯傳回錯誤的程序代碼。

// Read the D3DX effect file
WCHAR str[MAX_PATH];
ID3D10Blob* l_pBlob_Effect = NULL;
ID3D10Blob* l_pBlob_Errors = NULL;
hr = DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX10CompileEffectFromFile( str, NULL, NULL, 
    D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, 
    &l_pBlob_Effect, &l_pBlob_Errors );

LPVOID l_pError = NULL;
if( l_pBlob_Errors )
{
    l_pError = l_pBlob_Errors->GetBufferPointer();
    // then cast to a char* to see it in the locals window
}

轉譯效果 (Direct3D 10)