Sdílet prostřednictvím


Kompilace efektu (Direct3D 11)

Po vytvoření efektu je dalším krokem kompilace kódu pro kontrolu problémů se syntaxí.

Provedete to voláním jednoho z kompilačních rozhraní API (D3DX11CompileFromFile, D3DX11CompileFromMemorynebo D3DX11CompileFromResource ). Tato rozhraní API vyvolávají kompilátor efektů fxc.exe, který kompiluje kód HLSL. To je důvod, proč syntaxe kódu v efektu vypadá velmi podobně jako HLSL kód. (Existuje několik výjimek, které se budou zpracovávat později). Kompilátor efektů /hlsl kompilátor, fxc.exe, je k dispozici v sadě SDK ve složce nástrojů, aby shadery (nebo efekty) mohly být kompilovány offline, pokud zvolíte. Viz dokumentace ke spuštění kompilátoru z příkazového řádku.

Příklad

Tady je příklad kompilace souboru efektu.

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

Zahrnuje

Jedním z parametrů zkompilovacích rozhraní API je rozhraní include. Pokud chcete zahrnout přizpůsobené chování při čtení souboru include kompilátoru, vygenerujte jednu z těchto možností. Kompilátor toto vlastní chování spustí pokaždé, když vytvoří nebo zkompiluje efekt (který používá ukazatel zahrnutí). Chcete-li implementovat přizpůsobené chování zahrnutí, odvození třídy z ID3DInclude rozhraní. Tato třída poskytuje dvě metody: Open a Close. Implementujte vlastní chování v těchto metodách.

Hledání zahrnutí souborů

Ukazatel, který kompilátor předá v pParentData parametru Open obslužné rutiny include, nemusí odkazovat na kontejner, který obsahuje #include soubor, který kompilátor potřebuje ke kompilaci kódu shaderu. To znamená, že kompilátor může předat NULL v pParentData. Proto doporučujeme, aby obslužná rutina zahrnovala hledání vlastního seznamu umístění zahrnutí obsahu. Obslužná rutina zahrnutí může dynamicky přidávat nová umístění zahrnutí, protože přijímá tato umístění ve voláních metody Open.

V následujícím příkladu předpokládejme, že soubory zahrnutí kódu shaderu jsou uloženy v někde adresáři. Když kompilátor zavolá metodu Openinclude obslužnérutiny include, která otevře a přečte obsah někdeelse\foo.h, obslužná rutina include může uložit umístění někde adresář. Později, když kompilátor volá metodu include obslužné rutiny Open k otevření a čtení obsahu bar.h, může obslužná rutina zahrnutí automaticky hledat v někdeelse adresář pro bar.h.

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

Foo.h:
#include "bar.h"

Makra

Kompilace efektu může také převést ukazatel na makra, která jsou definována jinde. Předpokládejme například, že chcete upravit efekt v BasicHLSL10 tak, aby používala dvě makra: nula a jedna. Tady se zobrazí kód efektu, který používá dvě makra.

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

Tady je deklarace dvou maker.

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

Makra jsou pole s ukončenou hodnotou NULL. kde je každé makro definováno pomocí struktury D3D10_SHADER_MACRO.

Upravte volání efektu kompilace tak, aby odkazoval na makra.

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

Příznaky shaderu HLSL

Příznaky shaderu určují omezení shaderu kompilátoru HLSL. Tyto příznaky ovlivňují kód vygenerovaný kompilátorem shaderu následujícími způsoby:

  • Optimalizujte velikost kódu.
  • Zahrnutí informací o ladění, které brání řízení toku.
  • Ovlivňuje cíl kompilace a to, jestli může shader běžet na starším hardwaru.

Tyto příznaky lze logicky zkombinovat, pokud jste nezadáli dvě konfliktní charakteristiky. Seznam příznaků najdete v tématu D3D10_SHADER Konstanty.

FX Flags

Tyto příznaky použijte při vytváření efektu k definování chování kompilace nebo chování efektu za běhu. Seznam příznaků najdete v tématu D3D10_EFFECT Konstanty.

Kontrola chyb

Pokud během kompilace dojde k chybě, rozhraní API vrátí rozhraní, které obsahuje chyby z kompilátoru efektu. Toto rozhraní se nazývá ID3DBlob. Není přímo čitelný; Vrátíte-li však ukazatel na vyrovnávací paměť obsahující data (což je řetězec), můžete zobrazit všechny chyby kompilace.

Tento příklad obsahuje chybu v BasicHLSL.fx, první deklarace proměnné se vyskytuje dvakrát.

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

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

Tato chyba způsobí, že kompilátor vrátí následující chybu, jak je znázorněno na následujícím snímku obrazovky okna Kukátko v sadě Microsoft Visual Studio.

snímek obrazovky okna kukátka sady Visual Studio s chybou 0x01997fb8

Vzhledem k tomu, že kompilátor vrátí chybu v ukazateli LPVOID, přetypujte ji na řetězec znaků v okně Kukátko.

Tady je kód, který vrátí chybu z neúspěšné kompilace.

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

vykreslení efektu (Direct3D 11)