Compartilhar via


Compilar um efeito (Direct3D 10)

Depois que um efeito tiver sido criado, a primeira etapa é compilar o código para marcar para problemas de sintaxe. Isso é feito chamando uma das APIs de compilação (como D3DX10CompileEffectFromFile, D3DX10CompileEffectFromResource, D3DX10CompileEffectFromMemory). Essas API invocam o compilador de efeito fxc.exe que é o compilador usado para compilar o código HLSL. É por isso que a sintaxe do código em um efeito se parece muito com o código HLSL (há algumas exceções que serão tratadas posteriormente). A propósito, o compilador de efeito/compilador de hlsl (fxc.exe) está no SDK na pasta utilities para que você possa compilar seus sombreadores (ou efeitos) offline, se você escolher. Consulte a documentação para executar o compilador na linha de comando.

Aqui está um exemplo de compilação de um arquivo de efeito (do exemplo 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

Um parâmetro é uma interface include. Gere um destes se você quiser incluir um comportamento personalizado ao ler um arquivo de inclusão. Esse comportamento personalizado é executado sempre que um efeito (que usa o ponteiro include) é criado ou quando um efeito (que usa o ponteiro include) é compilado. Para implementar o comportamento de inclusão personalizado, derive uma classe da interface Include. Isso fornece seus dois métodos de classe: Abrir e Fechar. Implemente o comportamento personalizado nos métodos Abrir e Fechar.

Macros

A compilação de efeito também pode levar um ponteiro para macros definidas em outro lugar. Por exemplo, suponha que você deve modificar o efeito em BasicHLSL10, para usar duas macros: zero e uma. O código de efeito que usa as duas macros é mostrado aqui.

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

Aqui está a declaração para as duas macros.

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

As macros são uma matriz de macros terminada em NULL; em que cada macro é definida com um struct D3D_SHADER_MACRO .

Por fim, modifique a chamada de efeito de compilação para usar um ponteiro para as macros.

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

Sinalizadores de sombreador HLSL

Sinalizadores de sombreador especificam restrições de sombreador para o compilador HLSL. Esses sinalizadores afetam o código gerado pelo compilador de sombreador, incluindo:

  • Considerações de tamanho: otimize o código.
  • Considerações de depuração: incluindo informações de depuração, impedindo o controle de fluxo.
  • Considerações de hardware: o destino da compilação e se um sombreador pode ou não ser executado em hardware herdado.

Em geral, esses sinalizadores podem ser combinados logicamente, supondo que você não tenha especificado duas características conflitantes. Para obter uma listagem dos sinalizadores, consulte Constantes de efeito (Direct3D 10).

Sinalizadores FX

Esses sinalizadores usados ao criar um efeito para definir o comportamento da compilação ou o comportamento do efeito de runtime. Para obter uma listagem dos sinalizadores, consulte Constantes de efeito (Direct3D 10).

Verificando erros

Se durante a compilação ocorrer um erro, a API retornará uma interface que contém os erros retornados do compilador de efeito. Essa interface é chamada ID3D10Blob. No entanto, não é legível diretamente, retornando um ponteiro para o buffer que contém os dados (que é uma cadeia de caracteres), você pode ver quaisquer erros de compilação.

Neste exemplo, um erro foi introduzido no efeito BasicHLSL.fx copiando a primeira declaração de variável duas vezes.

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

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

Esse erro fez com que o compilador retornasse o erro a seguir, conforme mostrado na captura de tela a seguir da janela watch no Microsoft Visual Studio.

captura de tela da janela watch do Visual Studio

Como o erro é retornado em um ponteiro LPVOID, converta-o em uma cadeia de caracteres na janela watch.

Aqui está o código usado para retornar o erro da compilação com falha.

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

Renderizando um efeito (Direct3D 10)