编译效果 (Direct3D 10)
创作效果后,第一步是编译代码以检查语法问题。 这是通过调用其中一个编译 API(如 D3DX10CompileEffectFromFile、D3DX10CompileEffectFromResource、D3DX10CompileEffectFromMemory)来完成的。 这些 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 行为,请从 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 中监视窗口的以下屏幕截图所示。
visual Studio 监视窗口的
由于错误在 LPVOID 指针中返回,因此将其强制转换为监视窗口中的字符串。
下面是用于从失败的编译中返回错误的代码。
// 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
}
相关主题