编译效果 (Direct3D 10)

创作效果后,第一步是编译代码以检查语法问题。 为此, (调用 D3DX10CompileEffectFromFile、D3DX10CompileEffectFromResource、D3DX10CompileEffectFromMemory) 等编译 API。 这些 API 调用效果编译器fxc.exe这是用于编译 HLSL 代码的编译器。 这就是为什么效果中的代码语法看起来非常类似于 HLSL 代码的原因, (有一些异常将在稍后) 处理。 顺便说一下,效果编译器/hlsl 编译器 (fxc.exe) 位于实用工具文件夹的 SDK 中,以便你可以根据需要脱机编译着色器 (或效果) 。 请参阅从命令行运行编译器的文档。

下面是从 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 );

包括

一个参数是 include 接口。 如果要在读取包含文件时包含自定义行为,请生成其中一个。 每次创建使用包含指针) 的效果 (时,或者在编译使用包含指针) 的效果 (时,都会执行此自定义行为。 若要实现自定义的包含行为,请从 Include 接口派生类。 这为类提供了两种方法:Open 和 Close。 在 Open 和 Close 方法中实现自定义行为。

效果编译还可以获取指向在其他位置定义的宏的指针。 例如,假设你要修改 BasicHLSL10 中的效果,以使用两个宏:零和一个。 此处显示了使用两个宏的效果代码。

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

下面是两个宏的声明。

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

宏是以 NULL 结尾的宏数组;其中,每个宏都使用 D3D_SHADER_MACRO 结构定义。

最后,修改编译效果调用以获取指向宏的指针。

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

HLSL 着色器标志

着色器标志指定 HLSL 编译器的着色器约束。 这些标志影响着色器编译器生成的代码,包括:

  • 大小注意事项:优化代码。
  • 调试注意事项:包括调试信息,阻止流控制。
  • 硬件注意事项:编译目标以及着色器是否可以在旧硬件上运行。

通常,这些标志可以在逻辑上组合,前提是你未指定两个冲突的特征。 有关标志的列表,请参阅 效果常量 (Direct3D 10)

FX 标志

创建效果时使用的这些标志用于定义编译行为或运行时效果行为。 有关标志的列表,请参阅 效果常量 (Direct3D 10)

检查错误

如果在编译期间发生错误,API 将返回一个接口,其中包含从效果编译器返回的错误。 此接口称为 ID3D10Blob。 但是,通过返回指向包含数据 ((字符串) )的缓冲区的指针,无法直接读取该缓冲区,可以看到任何编译错误。

在此示例中,通过复制第一个变量声明两次,在 BasicHLSL.fx 效果中引入了错误。

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

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

此错误导致编译器返回以下错误,如 Microsoft Visual Studio 中watch窗口的以下屏幕截图所示。

Visual Studio watch窗口的屏幕截图

由于错误是在 LPVOID 指针中返回的,因此请将其强制转换为watch窗口中的字符串。

下面是用于从失败的编译中返回错误的代码。

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

(Direct3D 10) 呈现效果