这个类是用来创建着色器并设置输入布局的。

这个类比较特殊,它创建的着色器与Effect文件有关,effect文件是用高级着色语言(hlsl)编写的。

shadersclass.h

 1 #pragma once
 2 #include <d3d11.h>
 3 #include <d3dcompiler.h>
 4 #include <D3DX11.h>
 5 #include <xnamath.h>
 6 
 7 #pragma comment(lib,"d3dx11.lib")
 8 #pragma comment(lib,"d3d11.lib")
 9 #pragma comment(lib,"d3dcompiler.lib")
10 class shaderclass
11 {
12 public:
13     shaderclass();
14     ~shaderclass();
15     bool Initialize(ID3D11Device *device, ID3D11DeviceContext* context);
16     void Shutdown();
17 private:
18     bool CompileShaderFromFile(WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut);
19 private:
20     ID3DBlob* m_vsblob,*m_psblob;
21     ID3D11PixelShader *m_pixelshader;
22     ID3D11VertexShader *m_vertexshader;
23     ID3D11InputLayout *m_layout;
24 public:
25     void GetShaders(ID3D11VertexShader*& vs, ID3D11PixelShader*& ps);
26 };

这个着色器类比较简单,只创建了顶点着色器和像素着色器,还设置了一个简单的输入布局,这些工作都由Initialize()函数来做,私有函数CompileShaderFromFile()函数则是用来将effect文件编译成二进制文件的,GetShaders()则是用来获取创建好的着色器对象的。

shaderclass.cpp

  1 #include "shaderclass.h"
  2 
  3 
  4 shaderclass::shaderclass()
  5 {
  6 }
  7 
  8 
  9 shaderclass::~shaderclass()
 10 {
 11 }
 12 
 13 bool shaderclass::Initialize(ID3D11Device *device,ID3D11DeviceContext* context)
 14 {
 15     HRESULT hr = S_OK;
 16     bool result = CompileShaderFromFile(L"shader.fx", "VS", "vs_4_0", &m_vsblob);
 17     if (!result)
 18     {
 19         MessageBox(NULL,
 20             L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
 21         return false;
 22     }
 23     
 24     hr = device->CreateVertexShader(m_vsblob->GetBufferPointer(), m_vsblob->GetBufferSize(), NULL, &m_vertexshader);
 25     if (FAILED(hr))
 26     {
 27         return false;
 28     }
 29     
 30     result = CompileShaderFromFile(L"shader.fx", "PS", "ps_4_0", &m_psblob);
 31     if (!result)
 32     {
 33         MessageBox(NULL,
 34             L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
 35         return false;
 36     }
 37     
 38     hr = device->CreatePixelShader(m_psblob->GetBufferPointer(), m_psblob->GetBufferSize(), NULL, &m_pixelshader);
 39     if (FAILED(hr))
 40     {
 41         return false;
 42     }    
 43     D3D11_INPUT_ELEMENT_DESC layout[] =
 44     {
 45         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 46         { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },        
 47     };/////////////////
 48     UINT numElements = ARRAYSIZE(layout);    
 49 
 50     hr = device->CreateInputLayout(layout, numElements, m_vsblob->GetBufferPointer(),m_vsblob->GetBufferSize(), &m_layout);    
 51     if (FAILED(hr))
 52     {
 53         return false;
 54     }
 55     context->IASetInputLayout(m_layout);
 56 
 57     return true;
 58 }
 59 void shaderclass::Shutdown()
 60 {
 61     if (m_layout)
 62     {
 63         m_layout->Release();
 64     }
 65     if (m_pixelshader)
 66     {
 67         m_pixelshader->Release();
 68     }
 69     if (m_psblob)
 70     {
 71         m_psblob->Release();
 72     }
 73     if (m_vertexshader)
 74     {
 75         m_vertexshader->Release();
 76     }
 77     if (m_vsblob)
 78     {
 79         m_vsblob->Release();
 80     }
 81 }
 82 
 83 bool shaderclass::CompileShaderFromFile(WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut)
 84 {
 85     HRESULT hr = S_OK;
 86 
 87     DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
 88 #if defined( DEBUG ) || defined( _DEBUG )
 89     dwShaderFlags |= D3DCOMPILE_DEBUG;
 90 #endif
 91 
 92     ID3DBlob* pErrorBlob=0;
 93     hr = D3DX11CompileFromFile(szFileName, NULL, NULL, szEntryPoint, szShaderModel,
 94         dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL);
 95 
 96     if (FAILED(hr))
 97     {
 98         if (pErrorBlob != NULL)
 99             OutputDebugStringA((char*)pErrorBlob->GetBufferPointer());
100         if (pErrorBlob) pErrorBlob->Release();
101         return false;
102     }
103     if (pErrorBlob) 
104         pErrorBlob->Release();
105     
106     return true;
107 }
108 
109 void shaderclass::GetShaders(ID3D11VertexShader*& vs,ID3D11PixelShader*& ps)
110 {
111     vs = m_vertexshader;
112     ps = m_pixelshader;
113 }

Initialize():

  • 调用CompileShaderFromFile()函数编译effect文件里的顶点处理函数,得到二进制文件,根据二进制文件创建顶点着色器,CompileShaderFromFile()函数的第一个参数“shader.fx”就是effect文件
  • 编译effect文件里的像素处理函数,得到二进制文件并创建像素着色器
  • 填充输入布局描述数据结构,并创建输入布局,成功后设置输入布局

CompileShaderFromFile(): 里面只是单纯的调用dx11API D3DX11CompileFromFile()函数

整个类的编写非常简单,这只是因为我很简单的创建了两个着色器。如果要创建更复杂的着色器,还要学习很多。

另附上effect文件

shader.fx

 1 Texture2D txDiffuse : register(t0);
 2 SamplerState samLinear : register(s0);
 3 
 4 cbuffer ConstantBuffer : register(b0)
 5 {
 6     matrix World;
 7     matrix View;
 8     matrix Projection;
 9 }
10 
11 
12 struct VS_INPUT
13 {
14     float4 Pos : POSITION;
15     float4 Tex : TEXCOORD0;
16 };
17 struct PS_INPUT
18 {
19     float4 Pos : SV_POSITION;
20     float2 Tex : TEXCOORD0;
21 };
22 //--------------------------------------------------------------------------------------
23 // Vertex Shader
24 //--------------------------------------------------------------------------------------
25 PS_INPUT VS(VS_INPUT input)
26 {
27     PS_INPUT output = (PS_INPUT)0;
28     output.Pos = mul(input.Pos, World);
29     output.Pos = mul(output.Pos, View);
30     output.Pos = mul(output.Pos, Projection);
31     output.Tex = input.Tex;
32 
33     return output;
34 }
35 //--------------------------------------------------------------------------------------
36 // Pixel Shader
37 //--------------------------------------------------------------------------------------
38 float4 PS(PS_INPUT input) : SV_Target
39 {
40     return txDiffuse.Sample(samLinear, input.Tex);
41 }

 

 posted on 2016-06-14 23:34  Woody_245  阅读(755)  评论(0编辑  收藏  举报