Freigeben über


Kompilieren eines Effekts (Direct3D 10)

Nachdem ein Effekt erstellt wurde, besteht der erste Schritt darin, den Code zu kompilieren, um auf Syntaxprobleme zu prüfen. Dazu rufen Sie eine der Kompilierungs-APIs auf (z. B. D3DX10CompileEffectFromFile, D3DX10CompileEffectFromResource, D3DX10CompileEffectFromMemory). Diese API ruft den Effektcompiler fxc.exe auf, der zum Kompilieren von HLSL-Code verwendet wird. Aus diesem Grund sieht die Syntax für Code in einem Effekt sehr ähnlich wie HLSL-Code aus (es gibt einige Ausnahmen, die später behandelt werden). Übrigens befindet sich der Effektcompiler/hlsl-Compiler (fxc.exe) im SDK im Dienstprogrammordner, sodass Sie ihre Shader (oder Effekte) offline kompilieren können, wenn Sie dies auswählen. Informationen zum Ausführen des Compilers über die Befehlszeile finden Sie in der Dokumentation.

Hier ist ein Beispiel zum Kompilieren einer Effektdatei (aus dem BasicHLSL10-Beispiel).

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

Enthält

Ein Parameter ist eine Include-Schnittstelle. Generieren Sie eines dieser Elemente, wenn Sie beim Lesen einer Includedatei ein angepasstes Verhalten einschließen möchten. Dieses benutzerdefinierte Verhalten wird jedes Mal ausgeführt, wenn ein Effekt (der den Includezeiger verwendet) erstellt wird oder wenn ein Effekt (der den Includezeiger verwendet) kompiliert wird. Um angepasstes Includeverhalten zu implementieren, leiten Sie eine Klasse von der Include-Schnittstelle ab. Dadurch erhalten Sie zwei Methoden der Klasse: "Öffnen" und "Schließen". Implementieren Sie das benutzerdefinierte Verhalten in den Methoden "Öffnen" und "Schließen".

Macros

Die Effektkompilierung kann auch einen Zeiger auf Makros ausführen, die an anderer Stelle definiert sind. Angenommen, Sie wollten den Effekt in BasicHLSL10 ändern, um zwei Makros zu verwenden: Null und eins. Der Effektcode, der die beiden Makros verwendet, wird hier gezeigt.

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

Dies ist die Deklaration für die beiden Makros.

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

Die Makros sind ein null-beendetes Array von Makros; wobei jedes Makro mit einer D3D_SHADER_MACRO Struktur definiert ist.

Ändern Sie abschließend den Aufruf des Kompilierungseffekts, um einen Zeiger auf die Makros zu setzen.

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

HLSL-Shaderkennzeichnungen

Shaderkennzeichnungen geben Shadereinschränkungen für den HLSL-Compiler an. Diese Flags wirken sich auf den vom Shadercompiler generierten Code aus, einschließlich:

  • Überlegungen zur Größe: Optimieren des Codes.
  • Debugüberlegungen: Einschließlich Debuginformationen, Verhindern der Flusssteuerung.
  • Hardwareüberlegungen: Das Kompilierungsziel und ob ein Shader auf älteren Hardware ausgeführt werden kann.

Im Allgemeinen können diese Flags logisch kombiniert werden, vorausgesetzt, Sie haben nicht zwei widersprüchliche Merkmale angegeben. Eine Auflistung der Flags finden Sie unter Effektkonstanten (Direct3D 10).

FX-Flags

Diese Flags, die beim Erstellen eines Effekts zum Definieren des Kompilierungsverhaltens oder des Laufzeiteffektverhaltens verwendet werden. Eine Auflistung der Flags finden Sie unter Effektkonstanten (Direct3D 10).

Überprüfen von Fehlern

Wenn während der Kompilierung ein Fehler auftritt, gibt die API eine Schnittstelle zurück, die die vom Effektcompiler zurückgegebenen Fehler enthält. Diese Schnittstelle wird als ID3D10Blob bezeichnet. Sie ist jedoch nicht direkt lesbar, indem Sie einen Zeiger auf den Puffer zurückgeben, der die Daten enthält (eine Zeichenfolge), können Sie alle Kompilierungsfehler sehen.

In diesem Beispiel wurde ein Fehler in den BasicHLSL.fx-Effekt eingeführt, indem die erste Variablendeklaration zweimal kopiert wurde.

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

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

Dieser Fehler führte dazu, dass der Compiler den folgenden Fehler zurückgibt, wie im folgenden Screenshot des Überwachungsfensters in Microsoft Visual Studio gezeigt.

Screenshot des Visual Studio-Überwachungsfensters

Da der Fehler in einem LPVOID-Zeiger zurückgegeben wird, wandeln Sie ihn in eine Zeichenfolge im Überwachungsfenster um.

Hier ist der Code, der verwendet wird, um den Fehler aus der fehlgeschlagenen Kompilierung zurückzugeben.

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

Rendern eines Effekts (Direct3D 10)