• Directx11学习笔记【十四】 使用最新的Effect框架和SDK


      由于之前一直在看directx11龙书学习,因此sdk一直用的Microsoft DirectX SDK (June 2010) 版本,最近在stackoverflow上问dx11相关问题时,一直被大神吐槽为何还用已经废弃的directx sdk,由于directx sdk现在已经和windows sdk合并到一起了,只能去下windows sdk了。为了方便索性直接换了vs 2015社区版,里面自带了(windows sdk),既然sdk换了最新的,effect框架也要换最新的啊(Effect框架已经被微软开源托管在github上,https://github.com/Microsoft/FX11/wiki)。还有stackoverflow上都推荐DirectXTK,这方面中文资料非常少,只能靠自己慢慢看文档示例学了,等看得差不多了,会考虑用DirectXTK写的。以后教程还是基本跟着龙书走,我会将龙书实现的效果用自己封装的框架写一遍,尤其是一些过时的函数方法我也会换上对应的新方法。

      由于directx sdk集成在windows sdk中了,所以在建项目的时候就不用设置引用目录和库目录的路径了,只需设置链接库就可以了,还是挺方便的。由于换了sdk,一些方法参数之类的都略有不同,我又把之前的基类Dx11DemoBase重新封装了一遍,为了练习把前一个教程HillsDemo又重新写了一遍,体会一下有哪些改动。不同之处都在代码中给出了注释。

      前面教程编译shader用的是两个方法D3DX11CompileFromFile和D3DX11CreateEffectFromMemory,显得比较麻烦,在最新的FX11(Effect框架)中这两个方法已经废弃了,我们可以采用D3DX11CompileEffectFromFile来编译shader,一步到位尤为方便 

     1 //compile shader
     2     ID3DBlob* errorBlob;
     3     DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
     4 
     5 #if defined _DEBUG || defined DEBUG
     6     shaderFlags = D3DCOMPILE_DEBUG;
     7 #endif
     8 
     9     hr = D3DX11CompileEffectFromFile(L"color.fx", nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, shaderFlags,
    10         0, m_pd3dDevice, &m_pFx, &errorBlob);
    11     if (FAILED(hr))
    12     {
    13         MessageBox(nullptr, (LPCWSTR)errorBlob->GetBufferPointer(), L"error", MB_OK);
    14         return hr;
    15     }
    16 
    17     m_pTechnique = m_pFx->GetTechniqueByName("ColorTech");
    18     m_pFxWorldViewProj = m_pFx->GetVariableByName("gWorldViewProj")->AsMatrix();

      下面给出改动后的HillsDemo代码(其实大体差不多),在看新的官方实例时发现代码都是c++11风格(使用nullptr代替NULL,使用c++风格类型转换static_cast/reinterpret_cast,DirectXTK中大量使用智能指针等),因此咱也尽量保持相同的风格以养成写规范代码的好习惯。此外注释我也尽量用英文写,一方面有些用汉语不太好说明,另一方面由于要经常在stackoverflow上提问老外看不懂汉语还得临时改英文挺麻烦的。

      Base基类这次我们添加了depth/stencil缓冲,以便以后用到的时候不用再临时添加了。

     1 //create depth stencil texture
     2     D3D11_TEXTURE2D_DESC descDepth;
     3     descDepth.Width = m_width;
     4     descDepth.Height = m_height;
     5     descDepth.ArraySize = 1;
     6     descDepth.MipLevels = 1;
     7     descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
     8     descDepth.SampleDesc.Count = 1;
     9     descDepth.SampleDesc.Quality = 0;
    10     descDepth.Usage = D3D11_USAGE_DEFAULT;
    11     descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    12     descDepth.CPUAccessFlags = 0;
    13     descDepth.MiscFlags = 0;
    14     hr = m_pd3dDevice->CreateTexture2D(&descDepth, nullptr, &m_pDepthStencilBuffer);
    15     if (FAILED(hr))
    16         return hr;
    17 
    18     //create the depth stencil view
    19     D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
    20     ZeroMemory(&descDSV, sizeof(descDSV));
    21     descDSV.Format = descDepth.Format;
    22     descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    23     descDSV.Texture2D.MipSlice = 0;
    24     hr = m_pd3dDevice->CreateDepthStencilView(m_pDepthStencilBuffer, &descDSV, &m_pDepthStencilView);
    25     if (FAILED(hr))
    26         return hr;

      在实际Demo中每帧要clear一下

    1 //clear depth/stencil view
    2     m_pImmediateContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,
    3         1.0f, 0);

      

      Dx11DemoBase.h

     1 #ifndef _DX11DEMOBASE_H_
     2 #define _DX11DEMOBASE_H_
     3 
     4 #include <string>
     5 #include <windows.h>
     6 #include <d3d11.h>
     7 #include <d3dcompiler.h>
     8 #include <DirectXMath.h>//don't use xnamath.h
     9 #include <directxcolors.h>
    10 
    11 using namespace DirectX;
    12 
    13 class Dx11DemoBase
    14 {
    15 public:
    16     Dx11DemoBase();
    17     virtual ~Dx11DemoBase();
    18 
    19     std::wstring  m_mainWndCaption;                    //title
    20     float AspectRatio() const;                        //width/height
    21 
    22     bool InitDirect3D(HINSTANCE hInstance, HWND hWnd);
    23 
    24     void ShutDown();                                //release
    25 
    26     virtual bool LoadContent();                        //init concrete content
    27     virtual void UnLoadContent();                    //release 
    28 
    29     virtual void Update(float dt) = 0;
    30     virtual void Render() = 0;
    31 
    32     virtual void OnMouseDown(WPARAM btnState, int x, int y) {}
    33     virtual void OnMouseUp(WPARAM btnState, int x, int y) {}
    34     virtual void OnMouseMove(WPARAM btnState, int x, int y) {}
    35 
    36 protected:
    37     UINT                    m_width;                //window width
    38     UINT                    m_height;                //window height
    39     HINSTANCE                m_hInstance;            
    40     HWND                    m_hWnd;                    
    41     D3D_DRIVER_TYPE            m_driverType;             
    42     D3D_FEATURE_LEVEL        m_featureLevel;            
    43     ID3D11Device*            m_pd3dDevice;            
    44     ID3D11DeviceContext*    m_pImmediateContext;    
    45     IDXGISwapChain*            m_pSwapChain;            
    46     ID3D11RenderTargetView* m_pRenderTargetView;    
    47     ID3D11Texture2D*        m_pDepthStencilBuffer;    
    48     ID3D11DepthStencilView* m_pDepthStencilView;
    49 };
    50 
    51 #endif//_DX11DEMOBASE_H_

      Dx11DemoBase.cpp

      1 #include "Dx11DemoBase.h"
      2 
      3 Dx11DemoBase::Dx11DemoBase():
      4 m_mainWndCaption(L"Directx11 Application"),
      5 m_driverType(D3D_DRIVER_TYPE_HARDWARE),
      6 m_featureLevel(D3D_FEATURE_LEVEL_11_0),
      7 m_pd3dDevice(nullptr),
      8 m_pImmediateContext(nullptr),
      9 m_pRenderTargetView(nullptr),
     10 m_pDepthStencilBuffer(nullptr),
     11 m_pDepthStencilView(nullptr),
     12 m_pSwapChain(nullptr),
     13 m_hWnd(nullptr),
     14 m_width(800),
     15 m_height(600)
     16 {}
     17 
     18 Dx11DemoBase::~Dx11DemoBase()
     19 {
     20     ShutDown();
     21 }
     22 
     23 float Dx11DemoBase::AspectRatio() const
     24 {
     25     return static_cast<float>(m_width / m_height);
     26 }
     27 
     28 bool Dx11DemoBase::InitDirect3D(HINSTANCE hInstance, HWND hWnd)
     29 {
     30     HRESULT hr = S_OK;
     31     m_hInstance = hInstance;
     32     m_hWnd = hWnd;
     33     RECT rc;
     34     GetClientRect(m_hWnd, &rc);
     35     m_width = rc.right - rc.left;
     36     m_height = rc.bottom - rc.top;
     37 
     38     UINT createDeviceFlags = 0;
     39 
     40 #ifdef _DEBUG
     41     createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
     42 #endif
     43 
     44     D3D_DRIVER_TYPE driverTypes[] =
     45     {
     46         D3D_DRIVER_TYPE_HARDWARE,
     47         D3D_DRIVER_TYPE_WARP,
     48         D3D_DRIVER_TYPE_REFERENCE
     49     };
     50     UINT numDriverTypes = ARRAYSIZE(driverTypes);
     51 
     52     D3D_FEATURE_LEVEL featureLevels[] =
     53     {
     54         D3D_FEATURE_LEVEL_11_0,
     55         D3D_FEATURE_LEVEL_10_1,
     56         D3D_FEATURE_LEVEL_10_0
     57     };
     58     UINT numFeatureLevels = ARRAYSIZE(featureLevels);
     59 
     60     DXGI_SWAP_CHAIN_DESC sd;
     61     ZeroMemory(&sd, sizeof(sd));
     62     sd.BufferCount = 1;
     63     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
     64     sd.BufferDesc.Width = m_width;
     65     sd.BufferDesc.Height = m_height;
     66     sd.BufferDesc.RefreshRate.Numerator = 60;
     67     sd.BufferDesc.RefreshRate.Denominator = 1;
     68     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
     69     sd.OutputWindow = m_hWnd;
     70     sd.SampleDesc.Count = 1;    
     71     sd.SampleDesc.Quality = 0;
     72     sd.Windowed = TRUE;
     73 
     74     //create device and swapchain
     75     for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; ++driverTypeIndex)
     76     {
     77         hr = D3D11CreateDeviceAndSwapChain(nullptr, driverTypes[driverTypeIndex], nullptr,
     78             createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &m_pSwapChain,
     79             &m_pd3dDevice, &m_featureLevel, &m_pImmediateContext);
     80         if (SUCCEEDED(hr))
     81         {
     82             m_driverType = driverTypes[driverTypeIndex];
     83             break;
     84         }
     85     }
     86     if (FAILED(hr))
     87         return hr;
     88 
     89     //create render target view
     90     ID3D11Texture2D *pBackBuffer = nullptr;
     91     hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pBackBuffer));
     92     if (FAILED(hr))
     93         return hr;
     94 
     95     hr = m_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &m_pRenderTargetView);
     96     pBackBuffer->Release();
     97     if (FAILED(hr))
     98         return hr;
     99 
    100     m_pImmediateContext->OMSetRenderTargets(1, &m_pRenderTargetView, nullptr);
    101     
    102     //create depth stencil texture
    103     D3D11_TEXTURE2D_DESC descDepth;
    104     descDepth.Width = m_width;
    105     descDepth.Height = m_height;
    106     descDepth.ArraySize = 1;
    107     descDepth.MipLevels = 1;
    108     descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    109     descDepth.SampleDesc.Count = 1;
    110     descDepth.SampleDesc.Quality = 0;
    111     descDepth.Usage = D3D11_USAGE_DEFAULT;
    112     descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    113     descDepth.CPUAccessFlags = 0;
    114     descDepth.MiscFlags = 0;
    115     hr = m_pd3dDevice->CreateTexture2D(&descDepth, nullptr, &m_pDepthStencilBuffer);
    116     if (FAILED(hr))
    117         return hr;
    118 
    119     //create the depth stencil view
    120     D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
    121     ZeroMemory(&descDSV, sizeof(descDSV));
    122     descDSV.Format = descDepth.Format;
    123     descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    124     descDSV.Texture2D.MipSlice = 0;
    125     hr = m_pd3dDevice->CreateDepthStencilView(m_pDepthStencilBuffer, &descDSV, &m_pDepthStencilView);
    126     if (FAILED(hr))
    127         return hr;
    128 
    129     m_pImmediateContext->OMSetRenderTargets(1, &m_pRenderTargetView, m_pDepthStencilView);
    130 
    131     //setup the viewport
    132     D3D11_VIEWPORT vp;
    133     vp.Width = static_cast<float>(m_width);
    134     vp.Height = static_cast<float>(m_height);
    135     vp.MinDepth = 0.0f;
    136     vp.MaxDepth = 1.0f;
    137     vp.TopLeftX = 0.0f;
    138     vp.TopLeftY = 0.0f;
    139     m_pImmediateContext->RSSetViewports(1, &vp);
    140 
    141     return LoadContent();
    142 }
    143 
    144 
    145 void Dx11DemoBase::ShutDown()
    146 {
    147     UnLoadContent();
    148     if (m_pImmediateContext) m_pImmediateContext->ClearState();
    149 
    150     if (m_pRenderTargetView) m_pRenderTargetView->Release();
    151     if (m_pSwapChain) m_pSwapChain->Release();
    152     if (m_pImmediateContext) m_pImmediateContext->Release();
    153     if (m_pd3dDevice) m_pd3dDevice->Release();
    154     if (m_pDepthStencilBuffer) m_pDepthStencilBuffer->Release();
    155     if (m_pDepthStencilView) m_pDepthStencilView->Release();
    156 }
    157 
    158 bool Dx11DemoBase::LoadContent()
    159 {
    160     return true;
    161 }
    162 
    163 void Dx11DemoBase::UnLoadContent(){}

      GeometryGenerator类中代码没什么改变不再给出

    HillsDemo.h

     1 #ifndef _HILLSDEMO_H_
     2 #define _HILLSDEMO_H_
     3 
     4 #include "Dx11DemoBase.h"
     5 #include "d3dx11effect.h"
     6 #include "GeometryGenerator.h"
     7 
     8 
     9 #pragma comment(lib,"d3d11.lib")
    10 #pragma comment(lib,"Effects11.lib")
    11 #pragma comment(lib,"d3dcompiler.lib")
    12 #pragma comment(lib,"winmm.lib")
    13 #pragma comment(lib,"comctl32.lib")
    14 #pragma comment(lib,"dxguid.lib")
    15 
    16 class HillsDemo : public Dx11DemoBase
    17 {
    18 public:
    19     HillsDemo();
    20     ~HillsDemo();
    21 
    22     bool LoadContent() override;
    23     void UnLoadContent() override;
    24 
    25     void Update(float dt) override;
    26     void Render() override;
    27 
    28     void OnMouseDown(WPARAM btnState, int x, int y) override;
    29     void OnMouseUp(WPARAM btnState, int x, int y) override;
    30     void OnMouseMove(WPARAM btnState, int x, int y) override;
    31 private:
    32     ID3D11Buffer*                    m_pVertexBuffer;
    33     ID3D11Buffer*                    m_pIndexBuffer;
    34     ID3D11InputLayout*               m_pInputLayout;
    35 
    36     ID3DX11Effect*                   m_pFx;
    37     ID3DX11EffectTechnique*          m_pTechnique;
    38     ID3DX11EffectMatrixVariable*     m_pFxWorldViewProj;
    39     XMFLOAT4X4                       m_world;
    40     XMFLOAT4X4                       m_view;
    41     XMFLOAT4X4                       m_proj;
    42 
    43     
    44     UINT                             m_gridIndexCount;
    45     float                            m_theta;
    46     float                            m_phi;
    47     float                            m_radius;
    48     POINT                            m_lastMousePos;
    49 
    50     float GetHeight(float x, float z)const;
    51 
    52 };
    53 
    54 #endif//_HILLSDEMO_H_

    HillsDemo.cpp

      1 #include "HillsDemo.h"
      2 
      3 struct Vertex
      4 {
      5     XMFLOAT3 pos;
      6     XMFLOAT4 color;
      7     Vertex(XMFLOAT3 p, XMFLOAT4 c) : pos(p), color(c) {}
      8 };
      9 
     10 HillsDemo::HillsDemo() :m_pInputLayout(nullptr), m_pVertexBuffer(nullptr),m_pFx(nullptr), m_gridIndexCount(0),
     11 m_theta(1.5f*XM_PI), m_phi(0.1f*XM_PI), m_radius(200.0f)
     12 {
     13     XMMATRIX I = XMMatrixIdentity();
     14     XMStoreFloat4x4(&m_world, I);
     15     XMStoreFloat4x4(&m_view, I);
     16     XMStoreFloat4x4(&m_proj, I);
     17 }
     18 
     19 HillsDemo::~HillsDemo()
     20 {
     21 
     22 }
     23 
     24 bool HillsDemo::LoadContent()
     25 {
     26     HRESULT hr;
     27 
     28     //create vertex buffer
     29     GeometryGenerator::MeshData grid;
     30     GeometryGenerator geoGen;
     31     geoGen.CreateGrid(160.0f, 160.0f, 50, 50, grid);
     32     m_gridIndexCount = grid.indices.size();
     33 
     34     std::vector<Vertex> vertices(grid.vertices.size(), Vertex(XMFLOAT3(0, 0, 0), XMFLOAT4(0, 0, 0, 0)));
     35     for (UINT i = 0; i < grid.vertices.size(); ++i)
     36     {
     37         XMFLOAT3 p = grid.vertices[i].Position;
     38         p.y = GetHeight(p.x, p.z);
     39 
     40         vertices[i].pos = p;
     41 
     42         //render vertex with different color according to height
     43         if (p.y < -10.0f)
     44         {
     45             //sandy beach color
     46             vertices[i].color = XMFLOAT4(1.0f, 0.96f, 0.62f, 1.0f);
     47         }
     48         else if (p.y < 5.0f)
     49         {
     50             //dark yellow-green color
     51             vertices[i].color = XMFLOAT4(0.1f, 0.48f, 0.19f, 1.0f);
     52         }
     53         else if (p.y < 12.0f)
     54         {
     55             //light yellow-green color
     56             vertices[i].color = XMFLOAT4(0.48f, 0.77f, 0.46f, 1.0f);
     57         }
     58         else if (p.y < 20.f)
     59         {
     60             //dark brown color
     61             vertices[i].color = XMFLOAT4(0.45f, 0.39f, 0.34f, 1.0f);
     62         }
     63         else
     64         {
     65             //white snow color
     66             vertices[i].color = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
     67         }
     68     }
     69 
     70     D3D11_BUFFER_DESC vertexDesc;
     71     ZeroMemory(&vertexDesc, sizeof(vertexDesc));
     72     vertexDesc.Usage = D3D11_USAGE_IMMUTABLE;
     73     vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
     74     vertexDesc.ByteWidth = sizeof(Vertex)* grid.vertices.size();
     75     D3D11_SUBRESOURCE_DATA resourceData;
     76     ZeroMemory(&resourceData, sizeof(resourceData));
     77     resourceData.pSysMem = &vertices[0];
     78     hr = m_pd3dDevice->CreateBuffer(&vertexDesc, &resourceData, &m_pVertexBuffer);
     79     if (FAILED(hr))
     80     {
     81         return false;
     82     }
     83 
     84     //set vertex buffer
     85     UINT stride = sizeof(Vertex);
     86     UINT offset = 0;
     87     m_pImmediateContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);
     88     //set primitive topology
     89     m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
     90 
     91     //create index buffer
     92     D3D11_BUFFER_DESC indexDesc;
     93     ZeroMemory(&indexDesc, sizeof(indexDesc));
     94     indexDesc.Usage = D3D11_USAGE_IMMUTABLE;
     95     indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
     96     indexDesc.ByteWidth = sizeof(UINT)* m_gridIndexCount;
     97 
     98     D3D11_SUBRESOURCE_DATA indexData;
     99     ZeroMemory(&indexData, sizeof(indexData));
    100     indexData.pSysMem = &grid.indices[0];
    101     hr = m_pd3dDevice->CreateBuffer(&indexDesc, &indexData, &m_pIndexBuffer);
    102     if (FAILED(hr))
    103     {
    104         return false;
    105     }
    106 
    107     //set index buffer
    108     m_pImmediateContext->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
    109 
    110     //compile shader
    111     ID3DBlob* errorBlob;
    112     DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
    113 
    114 #if defined _DEBUG || defined DEBUG
    115     shaderFlags = D3DCOMPILE_DEBUG;
    116 #endif
    117 
    118     hr = D3DX11CompileEffectFromFile(L"color.fx", nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, shaderFlags,
    119         0, m_pd3dDevice, &m_pFx, &errorBlob);
    120     if (FAILED(hr))
    121     {
    122         MessageBox(nullptr, (LPCWSTR)errorBlob->GetBufferPointer(), L"error", MB_OK);
    123         return hr;
    124     }
    125     
    126     m_pTechnique = m_pFx->GetTechniqueByName("ColorTech");
    127     m_pFxWorldViewProj = m_pFx->GetVariableByName("gWorldViewProj")->AsMatrix();
    128 
    129 
    130     //define the input layout
    131     D3D11_INPUT_ELEMENT_DESC colorLayout[] =
    132     {
    133         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    134         { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
    135     };
    136 
    137     UINT numLayoutElements = ARRAYSIZE(colorLayout);
    138     D3DX11_PASS_DESC passDesc;
    139     m_pTechnique->GetPassByIndex(0)->GetDesc(&passDesc);
    140 
    141     //create the input layout
    142     hr = m_pd3dDevice->CreateInputLayout(colorLayout, numLayoutElements, passDesc.pIAInputSignature,
    143         passDesc.IAInputSignatureSize, &m_pInputLayout);
    144     if (FAILED(hr))
    145         return hr;
    146 
    147     //set input layout
    148     m_pImmediateContext->IASetInputLayout(m_pInputLayout);
    149 
    150     return true;
    151 }
    152 
    153 void HillsDemo::UnLoadContent()
    154 {
    155     if (m_pVertexBuffer) m_pVertexBuffer->Release();
    156     if (m_pIndexBuffer)    m_pIndexBuffer->Release();
    157     if (m_pInputLayout)    m_pInputLayout->Release();
    158     if (m_pTechnique) m_pTechnique->Release();    
    159 }
    160 
    161 void HillsDemo::Update(float dt)
    162 {
    163     float x = m_radius*sinf(m_phi)*cosf(m_theta);
    164     float z = m_radius*sinf(m_phi)*sinf(m_theta);
    165     float y = m_radius*cosf(m_phi);
    166 
    167     XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
    168     XMVECTOR target = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
    169     XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
    170 
    171     XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
    172     XMStoreFloat4x4(&m_view, V);
    173     XMMATRIX T = XMMatrixPerspectiveFovLH(XM_PIDIV4, m_width / static_cast<float>(m_height),
    174         1.0f, 1000.0f);
    175     XMStoreFloat4x4(&m_proj, T);
    176 }
    177 
    178 void HillsDemo::Render()
    179 {
    180     if (m_pImmediateContext == 0)
    181         return;
    182     //clear render target view
    183     float clearColor[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
    184     m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, clearColor);
    185     
    186     //clear depth/stencil view
    187     m_pImmediateContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,
    188         1.0f, 0);
    189 
    190     //set constant buffer
    191     XMMATRIX world = XMLoadFloat4x4(&m_world);
    192     XMMATRIX view = XMLoadFloat4x4(&m_view);
    193     XMMATRIX proj = XMLoadFloat4x4(&m_proj);
    194     XMMATRIX worldViewProj = world*view*proj;
    195 
    196 
    197     D3DX11_TECHNIQUE_DESC techDesc;
    198     m_pTechnique->GetDesc(&techDesc);
    199     for (UINT i = 0; i < techDesc.Passes; ++i)
    200     {
    201         m_pFxWorldViewProj->SetMatrix(reinterpret_cast<float*>(&worldViewProj));
    202         m_pTechnique->GetPassByIndex(i)->Apply(0, m_pImmediateContext);
    203         m_pImmediateContext->DrawIndexed(m_gridIndexCount, 0, 0);
    204     }
    205 
    206     m_pSwapChain->Present(0, 0);
    207 }
    208 
    209 void HillsDemo::OnMouseDown(WPARAM btnState, int x, int y)
    210 {
    211     m_lastMousePos.x = x;
    212     m_lastMousePos.y = y;
    213     SetCapture(m_hWnd);
    214 }
    215 
    216 void HillsDemo::OnMouseUp(WPARAM btnState, int x, int y)
    217 {
    218     ReleaseCapture();
    219 }
    220 
    221 //restrict the number
    222 template<typename T>
    223 static T Clamp(const T& x, const T& low, const T& high)
    224 {
    225     return x < low ? low : (x > high ? high : x);
    226 }
    227 
    228 void HillsDemo::OnMouseMove(WPARAM btnState, int x, int y)
    229 {
    230     if ((btnState & MK_LBUTTON) != 0)
    231     {
    232         // make each pixel correspond to a quarter of a degree.
    233         float dx = XMConvertToRadians(0.25f*static_cast<float>(x - m_lastMousePos.x));
    234         float dy = XMConvertToRadians(0.25f*static_cast<float>(y - m_lastMousePos.y));
    235 
    236         // update angles based on input to orbit camera around box.
    237         m_theta += dx;
    238         m_phi += dy;
    239 
    240         // restrict the angle mPhi.
    241         m_phi = Clamp(m_phi, 0.1f, XM_PI - 0.1f);
    242     }
    243     else if ((btnState & MK_RBUTTON) != 0)
    244     {
    245         // make each pixel correspond to 0.2 unit in the scene.
    246         float dx = 0.2f*static_cast<float>(x - m_lastMousePos.x);
    247         float dy = 0.2f*static_cast<float>(y - m_lastMousePos.y);
    248 
    249         // update the camera radius based on input.
    250         m_radius += dx - dy;
    251 
    252         // restrict the radius.
    253         m_radius = Clamp(m_radius, 50.0f, 500.0f);
    254     }
    255 
    256     m_lastMousePos.x = x;
    257     m_lastMousePos.y = y;
    258 }
    259 
    260 float HillsDemo::GetHeight(float x, float z) const
    261 {
    262     return 0.3f*(z*sinf(0.1f*x) + x*cosf(0.1f*z));
    263 }

    main.cpp

     1 #include <windows.h>
     2 #include <windowsx.h>
     3 #include <memory>
     4 #include "HillsDemo.h"
     5 using namespace std;
     6 
     7 std::shared_ptr<Dx11DemoBase> demo = make_shared<HillsDemo>();
     8 
     9 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    10 
    11 int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
    12 {
    13     UNREFERENCED_PARAMETER(hPrevInstance);
    14     UNREFERENCED_PARAMETER(lpCmdLine);
    15 
    16     WNDCLASSEX wcex;
    17     wcex.cbClsExtra = 0;
    18     wcex.cbSize = sizeof(wcex);
    19     wcex.cbWndExtra = 0;
    20     wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    21     wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    22     wcex.hIcon = LoadIcon(nullptr, IDI_WINLOGO);
    23     wcex.hIconSm = wcex.hIcon;
    24     wcex.hInstance = hInstance;
    25     wcex.lpfnWndProc = WndProc;
    26     wcex.lpszClassName = L"HillsDemo";
    27     wcex.lpszMenuName = nullptr;
    28     wcex.style = CS_HREDRAW | CS_VREDRAW;
    29 
    30     if (!RegisterClassEx(&wcex))
    31         return 0;
    32 
    33 
    34     RECT rc = { 0, 0, 800, 600 };
    35     AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false);
    36 
    37     HWND hwnd = CreateWindowEx(WS_EX_APPWINDOW, L"HillsDemo", L"HillsDemo", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
    38         CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance, nullptr);
    39 
    40     if (!hwnd)
    41         return 0;
    42 
    43     ShowWindow(hwnd, nShowCmd);
    44 
    45 
    46     bool result = demo->InitDirect3D(hInstance, hwnd);
    47     if (!result)
    48         return 0;
    49 
    50     MSG msg;
    51     ZeroMemory(&msg, sizeof(msg));
    52     while (msg.message != WM_QUIT)
    53     {
    54         if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
    55         {
    56             TranslateMessage(&msg);
    57             DispatchMessage(&msg);
    58         }
    59         demo->Update(0.0f);
    60         demo->Render();        
    61     }
    62     demo->ShutDown();
    63     return static_cast<int>(msg.wParam);
    64 }
    65 
    66 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    67 {
    68     PAINTSTRUCT paintStruct;
    69     HDC hdc;
    70     switch (message)
    71     {
    72     case WM_PAINT:
    73         hdc = BeginPaint(hWnd, &paintStruct);
    74         EndPaint(hWnd, &paintStruct);
    75         break;
    76     case WM_DESTROY:
    77         PostQuitMessage(0);
    78         break;
    79     case WM_LBUTTONDOWN:
    80     case WM_MBUTTONDOWN:
    81     case WM_RBUTTONDOWN:
    82         demo->OnMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
    83         return 0;
    84     case WM_LBUTTONUP:
    85     case WM_MBUTTONUP:
    86     case WM_RBUTTONUP:
    87         demo->OnMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
    88         return 0;
    89     case WM_MOUSEMOVE:
    90         demo->OnMouseMove(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
    91         return 0;
    92     default:
    93         return DefWindowProc(hWnd, message, wParam, lParam);
    94     }
    95     return 0;
    96 }

    好了代码就这些了,最后让我们看张图缓解下疲劳吧

  • 相关阅读:
    go基础系列~定义新的数据类型
    go基础类型map类型
    redis基础系列~基础监控模板
    事务的隔离级别
    ASP.NET Core 中间件的几种实现方式
    asp.net core 认证和授权实例详解
    快速理解ASP.NET Core的认证与授权
    C# Hashtable、HashSet和Dictionary的区别
    C# 中使用 Redis 简单存储
    ASP.NET Core 中间件
  • 原文地址:https://www.cnblogs.com/zhangbaochong/p/5535912.html
Copyright © 2020-2023  润新知