Compilare un effetto (Direct3D 10)

Dopo aver creato un effetto, il primo passaggio consiste nel compilare il codice per verificare la presenza di problemi di sintassi. Questa operazione viene eseguita chiamando una delle API di compilazione (ad esempio D3DX10CompileEffectFromFile, D3DX10CompileEffectFromResource, D3DX10CompileEffectFromMemory). Queste API richiamano il compilatore di effetti fxc.exe che è il compilatore usato per compilare il codice HLSL. Questo è il motivo per cui la sintassi per il codice in un effetto è molto simile al codice HLSL (esistono alcune eccezioni che verranno gestite in un secondo momento). In questo modo, il compilatore di effetti/hlsl compilatore (fxc.exe) si trova nell'SDK nella cartella utilità in modo che sia possibile compilare gli shader (o gli effetti) offline se si sceglie. Vedere la documentazione per l'esecuzione del compilatore dalla riga di comando.

Ecco un esempio di compilazione di un file di effetto (dall'esempio 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 );

Includes

Un parametro è un'interfaccia di inclusione. Generare uno di questi se si vuole includere un comportamento personalizzato durante la lettura di un file di inclusione. Questo comportamento personalizzato viene eseguito ogni volta che viene compilato un effetto che usa il puntatore di inclusione o quando viene compilato un effetto (che usa il puntatore di inclusione). Per implementare il comportamento di inclusione personalizzato, derivare una classe dall'interfaccia Include. In questo modo vengono forniti due metodi: Apri e Chiudi. Implementare il comportamento personalizzato nei metodi Apri e Chiudi.

Macro

La compilazione degli effetti può anche richiedere un puntatore alle macro definite altrove. Si supponga, ad esempio, di modificare l'effetto in BasicHLSL10, per usare due macro: zero e uno. Il codice dell'effetto che usa le due macro viene visualizzato qui.

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

Ecco la dichiarazione per le due macro.

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

Le macro sono una matrice terminata NULL di macro; dove ogni macro viene definita con uno struct D3D_SHADER_MACRO .

Infine, modificare la chiamata di effetto di compilazione per richiedere un puntatore alle macro.

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

Flag HLSL Shader

I flag shader specificano vincoli shader al compilatore HLSL. Questi flag influisce sul codice generato dal compilatore shader, tra cui:

  • Considerazioni sulle dimensioni: ottimizzare il codice.
  • Considerazioni sul debug: incluse le informazioni di debug, che impediscono il controllo del flusso.
  • Considerazioni sull'hardware: la destinazione di compilazione e se un shader può essere eseguito sull'hardware legacy.

In generale, questi flag possono essere combinati logicamente, presupponendo che non siano state specificate due caratteristiche in conflitto. Per un elenco dei flag, vedere Costanti effetto (Direct3D 10).

Flag FX

Questi flag usati durante la creazione di un effetto per definire il comportamento di compilazione o il comportamento dell'effetto di runtime. Per un elenco dei flag, vedere Costanti effetto (Direct3D 10).

Controllo degli errori

Se durante la compilazione si verifica un errore, l'API restituisce un'interfaccia contenente gli errori restituiti dal compilatore dell'effetto. Questa interfaccia è denominata ID3D10Blob. Non è tuttavia leggibile direttamente, restituendo un puntatore al buffer contenente i dati (ovvero una stringa), è possibile visualizzare eventuali errori di compilazione.

In questo esempio è stato introdotto un errore nell'effetto BasicHLSL.fx copiando la prima dichiarazione di variabile due volte.

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

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

Questo errore ha causato al compilatore di restituire l'errore seguente, come illustrato nella schermata seguente della finestra di watch in Microsoft Visual Studio.

schermata della finestra di watch di Visual Studio

Poiché l'errore viene restituito in un puntatore LPVOID, eseguirne il cast in una stringa di caratteri nella finestra watch.

Ecco il codice usato per restituire l'errore dalla compilazione non riuscita.

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

Rendering di un effetto (Direct3D 10)