Dela via


Kompilera en effekt (Direct3D 11)

När en effekt har skapats är nästa steg att kompilera koden för att söka efter syntaxproblem.

Det gör du genom att anropa någon av kompilerings-API:erna (D3DX11CompileFromFile, D3DX11CompileFromMemoryeller D3DX11CompileFromResource ). Dessa API:er anropar effektkompilatorn fxc.exe, som kompilerar HLSL-kod. Därför ser syntaxen för kod i en effekt ut ungefär som HLSL-kod. (Det finns några undantag som kommer att hanteras senare). Kompilatorn/hlsl-kompilatorn för effekt, fxc.exe, är tillgänglig i SDK:t i mappen verktyg så att skuggningar (eller effekter) kan kompileras offline om du väljer det. Se dokumentationen för att köra kompilatorn från kommandoraden.

Exempel

Här är ett exempel på kompilering av en effektfil.

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 );

Innehåller

En parameter för kompilerings-API:erna är ett include-gränssnitt. Generera en av dessa om du vill inkludera ett anpassat beteende när kompilatorn läser en inkluderingsfil. Kompilatorn kör det här anpassade beteendet varje gång den skapar eller kompilerar en effekt (som använder inkluderingspekaren). Om du vill implementera anpassat inkluderingsbeteende härleder du en klass från ID3DInclude-gränssnittet. Det ger klassen två metoder: Öppna och Stäng. Implementera det anpassade beteendet i dessa metoder.

Söka efter inkluderingsfiler

Pekaren som kompilatorn skickar i parametern pParentData till include-hanterarens Metoden Öppna pekar kanske inte på den container som innehåller den #include fil som kompilatorn behöver för att kompilera skuggningskoden. Kompilatorn kan alltså skicka NULL- i pParentData. Därför rekommenderar vi att din include-hanterare söker i sin egen lista över inkluderingsplatser för innehåll. Din inkluderingshanterare kan dynamiskt lägga till nya inkluderingsplatser när den tar emot dessa platser i anrop till metoden Open.

I följande exempel antar vi att skuggningskodens inkluderingsfiler båda lagras i någonstans katalog. När kompilatorn anropar metoden include handler's Open för att öppna och läsa innehållet i somewhereelse\foo.hkan include-hanteraren spara platsen för någonstans i katalogen. När kompilatorn senare anropar include-hanterarens Open-metod för att öppna och läsa innehållet i bar.hkan include-hanteraren automatiskt söka i någonstans katalog efter bar.h.

Main.hlsl:
#include "somewhereelse\foo.h"

Foo.h:
#include "bar.h"

Makron

Effektkompilering kan också ta en pekare till makron som definieras någon annanstans. Anta till exempel att du vill ändra effekten i BasicHLSL10 för att använda två makron: noll och ett. Effektkoden som använder de två makrona visas här.

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

Här är deklarationen för de två makrona.

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

Makrona är en NULL-avslutad matris med makron. där varje makro definieras med hjälp av en D3D10_SHADER_MACRO struct.

Ändra kompileringseffektanropet för att ta en pekare till makrona.

D3DX11CompileFromFile( str, Shader_Macros, NULL, pFunctionName, 
                       pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL, 
                       NULL, &pBlob, &pErrorBlob, NULL );    

HLSL Shader-flaggor

Skuggningsflaggor anger skuggningsbegränsningar för HLSL-kompilatorn. Dessa flaggor påverkar koden som genereras av skuggningskompilatorn på följande sätt:

  • Optimera kodstorleken.
  • Inklusive felsökningsinformation, vilket förhindrar flödeskontroll.
  • Påverkar kompileringsmålet och om en skuggning kan köras på äldre maskinvara.

Dessa flaggor kan kombineras logiskt om du inte har angett två motstridiga egenskaper. En lista över flaggorna finns i D3D10_SHADER Konstanter.

FX-flaggor

Använd dessa flaggor när du skapar en effekt för att definiera antingen kompileringsbeteende eller körningseffektbeteende. En lista över flaggorna finns i D3D10_EFFECT Konstanter.

Kontrollera fel

Om ett fel uppstår under kompilering returnerar API:et ett gränssnitt som innehåller felen från effektkompilatorn. Det här gränssnittet kallas ID3DBlob. Den är inte direkt läsbar. Men genom att returnera en pekare till bufferten som innehåller data (som är en sträng) kan du se eventuella kompileringsfel.

Det här exemplet innehåller ett fel i BasicHLSL.fx, den första variabeldeklarationen inträffar två gånger.

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

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

Det här felet gör att kompilatorn returnerar följande fel, som visas i följande skärmbild av bevakningsfönstret i Microsoft Visual Studio.

skärmbild av visningsfönstret i Visual Studio med ett 0x01997fb8 fel

Eftersom kompilatorn returnerar felet i en LPVOID-pekare skickar du det till en teckensträng i bevakningsfönstret.

Här är koden som returnerar felet från den misslyckade kompilering.

// 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
}

Återgivning av en effekt (Direct3D 11)