• C++小项目:directx11图形程序(五):shadersclass


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

    这个类比较特殊,它创建的着色器与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 }
  • 相关阅读:
    EF Code First一对一、一对多、多对多关联关系配置
    ASP.NET MVC 3.0 HTML辅助方法
    CSS常用命名
    ExtJS3.4.0系列:ExtJS下载使用
    在HTTP响应标题中隐藏ASP.NET MVC的版本
    ASP.NET MVC动作过滤器
    Sql Server系列:使用TransactSQL编程
    ExtJS3.4.0系列:Ext.Panel
    Sql Server系列:Select检索数据
    ASP.NET MVC资源文件多语言实现方式
  • 原文地址:https://www.cnblogs.com/woody-245/p/5585890.html
Copyright © 2020-2023  润新知