Using Shaders in Direct3D 10
Using Shaders in Direct3D 10
The pipeline has three shader stages and each one is programmed with an HLSL shader. All Direct3D 10 shaders are written in HLSL, targeting shader model 4.
|
Differences between Direct3D 9 and Direct3D 10:
Unlike Direct3D 9 shader models which could be authored in an intermediate assembly language, shader model 4.0 shaders are only authored in HLSL. Offline compilation of shaders into device-consumable bytecode is still supported, and recommended for most scenarios.
|
This example uses only a vertex shader. Because all shaders are built from the common shader core, learning how to use a vertex shader is very similar to using a geometry or pixel shader.
Once you have authored an HLSL shader (this example uses the vertex shader HLSLWithoutFX.vsh), you will need to prepare it for the particular pipeline stage that will use it. To do this you need to:
These steps need to be repeated for each shader in the pipeline.
Compile a Shader
The first step is to compile the shader, to check to see that you have coded the HLSL statements correctly. This is done by calling D3D10CompileShader and supplying it with several parameters as shown here:
IPD3D10Blob * pBlob;
// Compile the vertex shader from the file
D3D10CompileShader( strPath, strlen( strPath ), "HLSLWithoutFX.vsh",
NULL, NULL, "Ripple", "vs_4_0", dwShaderFlags, &pBlob, NULL );
This function takes the following parameters:
If the shader compiles successfully, a pointer to the shader code is returned as a ID3D10Blob interface. It is called the Blob interface because the pointer is to a location in memory that is made up of an array of DWORD's. The interface is provided so that you can get a pointer to the compiled shader which you will need in the next step.
Beginning with the December 2006 SDK, the DirectX 10 HLSL compiler is now the default compiler in both DirectX 9 and DirectX 10. See Effect-Compiler Tool for details.
Get a Pointer to a Compiled Shader
Several API methods require a pointer to a compiled shader. This argument is usually called pShaderBytecode because it points to a compiled shader represented as a sequence of byte codes. To get a pointer to a compiled shader, first compile the shader by calling D3D10CompileShader or a similar function. If compilation is successful, the compiled shader is returned in an ID3D10Blob interface. Finally, use the ID3D10Blob::GetBufferPointer method to return the pointer.
Create a Shader Object
Once the shader is compiled, call CreateVertexShader to create the shader object:
ID3D10VertexShader ** ppVertexShader
ID3D10Blob pBlob;
// Create the vertex shader
hr = pd3dDevice->CreateVertexShader( (DWORD*)pBlob->GetBufferPointer(),
pBlob->GetBufferSize(), &ppVertexShader );
// Release the pointer to the compiled shader once you are done with it
pBlob->Release();
To create the shader object, pass the pointer to the compiled shader into CreateVertexShader. Since you had to successfully compile the shader first, this call will almost certainly pass, unless you have a memory problem on your machine.
You can create as many shader objects as you like and simply keep pointers to them. This same mechanism works for geometry and pixel shaders assuming you match the shader profiles (when you call the compile method) to the interface names (when you call the create method).
Set the Shader Object
The last step is set the shader to the pipeline stage. Since there are three shader stages in the pipeline, you will need to make three API calls, one for each stage.
// Set a vertex shader
pd3dDevice->VSSetShader( g_pVS10 );
The call to VSSetShader takes the pointer to the vertex shader created in step 1. This sets the shader in the device. The vertex shader stage is now initialized with its vertex shader code, all that remains is initializing any shader variables.
Repeat for all 3 Shader Stages
Repeat these same set of steps to build any vertex or pixel shader or even a geometry shader that outputs to the pixel shader.
See Also
Compiling Shaders