Procedura: Compilare uno shader
In genere si usa il compilatore di codice HLSL fxc.exe come parte del processo di compilazione per compilare il codice shader. Per altre info su questo argomento, vedi Compilazione di shader. Questo argomento illustra come usare la funzione D3DCompileFromFile in fase di esecuzione per compilare il codice shader.
Per compilare uno shader:
- Compilare il codice shader HLSL chiamando D3DCompileFromFile.
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined( DEBUG ) || defined( _DEBUG ) flags |= D3DCOMPILE_DEBUG; #endif // Prefer higher CS shader profile when possible as CS 5.0 provides better performance on 11-class hardware. LPCSTR profile = ( device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0 ) ? "cs_5_0" : "cs_4_0"; const D3D_SHADER_MACRO defines[] = { "EXAMPLE_DEFINE", "1", NULL, NULL }; ID3DBlob* shaderBlob = nullptr; ID3DBlob* errorBlob = nullptr; HRESULT hr = D3DCompileFromFile( srcFile, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, entryPoint, profile, flags, 0, &shaderBlob, &errorBlob );
Nell'esempio di codice seguente viene illustrato come compilare vari shader.
Nota
Per questo codice di esempio sono necessari Windows SDK 8.0 e il file d3dcompiler_44.dll dalla cartella %PROGRAM_FILE%\Windows Kits\8.0\Redist\D3D\<arch> nel percorso. Le app di Windows Store supportano la compilazione in fase di esecuzione per lo sviluppo, ma non per la distribuzione.
#define _WIN32_WINNT 0x600
#include <stdio.h>
#include <d3dcompiler.h>
#pragma comment(lib,"d3dcompiler.lib")
HRESULT CompileShader( _In_ LPCWSTR srcFile, _In_ LPCSTR entryPoint, _In_ LPCSTR profile, _Outptr_ ID3DBlob** blob )
{
if ( !srcFile || !entryPoint || !profile || !blob )
return E_INVALIDARG;
*blob = nullptr;
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
flags |= D3DCOMPILE_DEBUG;
#endif
const D3D_SHADER_MACRO defines[] =
{
"EXAMPLE_DEFINE", "1",
NULL, NULL
};
ID3DBlob* shaderBlob = nullptr;
ID3DBlob* errorBlob = nullptr;
HRESULT hr = D3DCompileFromFile( srcFile, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE,
entryPoint, profile,
flags, 0, &shaderBlob, &errorBlob );
if ( FAILED(hr) )
{
if ( errorBlob )
{
OutputDebugStringA( (char*)errorBlob->GetBufferPointer() );
errorBlob->Release();
}
if ( shaderBlob )
shaderBlob->Release();
return hr;
}
*blob = shaderBlob;
return hr;
}
int main()
{
// Compile vertex shader
ID3DBlob *vsBlob = nullptr;
HRESULT hr = CompileShader( L"BasicHLSL11_VS.hlsl", "VSMain", "vs_4_0_level_9_1", &vsBlob );
if ( FAILED(hr) )
{
printf("Failed compiling vertex shader %08X\n", hr );
return -1;
}
// Compile pixel shader
ID3DBlob *psBlob = nullptr;
hr = CompileShader( L"BasicHLSL11_PS.hlsl", "PSMain", "ps_4_0_level_9_1", &psBlob );
if ( FAILED(hr) )
{
vsBlob->Release();
printf("Failed compiling pixel shader %08X\n", hr );
return -1;
}
printf("Success\n");
// Clean up
vsBlob->Release();
psBlob->Release();
return 0;
}
Nell'esempio di codice precedente vengono compilati i blocchi di codice pixel e vertex shader nei file BasicHLSL11_PS.hlsl e BasicHLSL11_VS.hlsl. Ecco il codice in BasicHLSL11_PS.hlsl:
//--------------------------------------------------------------------------------------
// File: BasicHLSL11_PS.hlsl
//
// The pixel shader file for the BasicHLSL11 sample.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Globals
//--------------------------------------------------------------------------------------
cbuffer cbPerObject : register( b0 )
{
float4 g_vObjectColor : packoffset( c0 );
};
cbuffer cbPerFrame : register( b1 )
{
float3 g_vLightDir : packoffset( c0 );
float g_fAmbient : packoffset( c0.w );
};
//--------------------------------------------------------------------------------------
// Textures and Samplers
//--------------------------------------------------------------------------------------
Texture2D g_txDiffuse : register( t0 );
SamplerState g_samLinear : register( s0 );
//--------------------------------------------------------------------------------------
// Input / Output structures
//--------------------------------------------------------------------------------------
struct PS_INPUT
{
float3 vNormal : NORMAL;
float2 vTexcoord : TEXCOORD0;
};
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PSMain( PS_INPUT Input ) : SV_TARGET
{
float4 vDiffuse = g_txDiffuse.Sample( g_samLinear, Input.vTexcoord );
float fLighting = saturate( dot( g_vLightDir, Input.vNormal ) );
fLighting = max( fLighting, g_fAmbient );
return vDiffuse * fLighting;
}
Ecco il codice in BasicHLSL11_VS.hlsl:
//--------------------------------------------------------------------------------------
// File: BasicHLSL11_VS.hlsl
//
// The vertex shader file for the BasicHLSL11 sample.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Globals
//--------------------------------------------------------------------------------------
cbuffer cbPerObject : register( b0 )
{
matrix g_mWorldViewProjection : packoffset( c0 );
matrix g_mWorld : packoffset( c4 );
};
//--------------------------------------------------------------------------------------
// Input / Output structures
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
float4 vPosition : POSITION;
float3 vNormal : NORMAL;
float2 vTexcoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float3 vNormal : NORMAL;
float2 vTexcoord : TEXCOORD0;
float4 vPosition : SV_POSITION;
};
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VSMain( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.vPosition = mul( Input.vPosition, g_mWorldViewProjection );
Output.vNormal = mul( Input.vNormal, (float3x3)g_mWorld );
Output.vTexcoord = Input.vTexcoord;
return Output;
}
Argomenti correlati