Compilar um efeito (Direct3D 11)
Depois que um efeito tiver sido criado, a próxima etapa é compilar o código para marcar para problemas de sintaxe.
Faça isso chamando uma das APIs de compilação (D3DX11CompileFromFile, D3DX11CompileFromMemory ou D3DX11CompileFromResource ). Essas APIs invocam o fxc.exe do compilador de efeito, que compila 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). O compilador de efeito/compilador hlsl, fxc.exe, está disponível no SDK na pasta utilities para que os sombreadores (ou efeitos) possam ser compilados offline se você escolher. Consulte a documentação para executar o compilador na linha de comando.
- Exemplo
- Includes
- Pesquisando arquivos de inclusão
- Macros
- Sinalizadores de sombreador HLSL
- Sinalizadores FX
- Verificando erros
- Tópicos relacionados
Exemplo
Aqui está um exemplo de compilação de um arquivo de efeito.
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 );
Includes
Um parâmetro das APIs de compilação é uma interface include. Gere um deles se você quiser incluir um comportamento personalizado quando o compilador ler um arquivo de inclusão. O compilador executa esse comportamento personalizado sempre que cria ou compila um efeito (que usa o ponteiro include). Para implementar o comportamento de inclusão personalizado, derive uma classe da interface ID3DInclude . Isso fornece à sua classe dois métodos: Abrir e Fechar. Implemente o comportamento personalizado nesses métodos.
Pesquisando arquivos de inclusão
O ponteiro que o compilador passa no parâmetro pParentData para o método Open do manipulador de inclusão pode não apontar para o contêiner que inclui o arquivo #include que o compilador precisa para compilar o código do sombreador. Ou seja, o compilador pode passar NULL em pParentData. Portanto, recomendamos que o manipulador de inclusão pesquise sua própria lista de locais de inclusão para conteúdo. O manipulador de inclusão pode adicionar dinamicamente novos locais de inclusão, pois ele recebe esses locais em chamadas para seu método Open .
No exemplo a seguir, suponha que os arquivos de inclusão do código de sombreador sejam armazenados no diretório somewhereelse . Quando o compilador chama o método Open do manipulador include para abrir e ler o conteúdo de somewhereelse\foo.h, o manipulador include pode salvar o local do diretório somewhereelse . Posteriormente, quando o compilador chama o método Open do manipulador include para abrir e ler o conteúdo de bar.h, o manipulador de inclusão pode pesquisar automaticamente no diretório somewhereelse para bar.h.
Main.hlsl:
#include "somewhereelse\foo.h"
Foo.h:
#include "bar.h"
Macros
A compilação de efeito também pode usar um ponteiro para macros definidas em outro lugar. Por exemplo, suponha que você queira 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.
D3D10_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 usando um struct D3D10_SHADER_MACRO .
Modifique a chamada de efeito de compilação para usar um ponteiro para as macros.
D3DX11CompileFromFile( str, Shader_Macros, NULL, pFunctionName,
pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL,
NULL, &pBlob, &pErrorBlob, 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 das seguintes maneiras:
- Otimize o tamanho do código.
- Incluindo informações de depuração, o que impede o controle de fluxo.
- Afeta o destino de compilação e se um sombreador pode ser executado em hardware herdado.
Esses sinalizadores poderão ser combinados logicamente se você não tiver especificado duas características conflitantes. Para obter uma listagem dos sinalizadores , consulte Constantes D3D10_SHADER.
Sinalizadores FX
Use esses sinalizadores 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 D3D10_EFFECT.
Verificando erros
Se durante a compilação ocorrer um erro, a API retornará uma interface que contém os erros do compilador de efeito. Essa interface é chamada ID3DBlob. Não é diretamente legível; no entanto, retornando um ponteiro para o buffer que contém os dados (que é uma cadeia de caracteres), você pode ver quaisquer erros de compilação.
Este exemplo contém um erro no BasicHLSL.fx, a primeira declaração de variável ocorre 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 faz com que o compilador retorne o erro a seguir, conforme mostrado na captura de tela a seguir da janela Inspeção no Microsoft Visual Studio.
Como o compilador retorna o erro em um ponteiro LPVOID, converta-o em uma cadeia de caracteres na janela Inspeção.
Este é o código que retorna o erro da compilação com falha.
// 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
}
Tópicos relacionados