1#include "pch.h"
2#include "Direct3DBase.h"
3
4using namespace DirectX;
5using namespace Microsoft::WRL;
6using namespace Windows::UI::Core;
7using namespace Windows::Foundation;
8using namespace Windows::Graphics::Display;
9
10// Constructor.
11Direct3DBase::Direct3DBase()
12{
13}
14
15// Initialize the Direct3D resources required to run.
16void Direct3DBase::Initialize()
17{
18    CreateDeviceResources();
19}
20
21// These are the resources that depend on the device.
22void Direct3DBase::CreateDeviceResources()
23{
24    // This flag adds support for surfaces with a different color channel ordering
25    // than the API default. It is required for compatibility with Direct2D.
26    UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
27
28#if defined(_DEBUG)
29    // If the project is in a debug build, enable debugging via SDK Layers with this flag.
30    creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
31#endif
32
33    // This array defines the set of DirectX hardware feature levels this app will support.
34    // Note the ordering should be preserved.
35    // Don't forget to declare your application's minimum required feature level in its
36    // description.  All applications are assumed to support 9.1 unless otherwise stated.
37    D3D_FEATURE_LEVEL featureLevels[] =
38    {
39        D3D_FEATURE_LEVEL_11_1,
40        D3D_FEATURE_LEVEL_11_0,
41        D3D_FEATURE_LEVEL_10_1,
42        D3D_FEATURE_LEVEL_10_0,
43        D3D_FEATURE_LEVEL_9_3
44    };
45
46    // Create the Direct3D 11 API device object and a corresponding context.
47    ComPtr<ID3D11Device> device;
48    ComPtr<ID3D11DeviceContext> context;
49    DX::ThrowIfFailed(
50        D3D11CreateDevice(
51            nullptr, // Specify nullptr to use the default adapter.
52            D3D_DRIVER_TYPE_HARDWARE,
53            nullptr,
54            creationFlags, // Set set debug and Direct2D compatibility flags.
55            featureLevels, // List of feature levels this app can support.
56            ARRAYSIZE(featureLevels),
57            D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION.
58            &device, // Returns the Direct3D device created.
59            &m_featureLevel, // Returns feature level of device created.
60            &context // Returns the device immediate context.
61            )
62        );
63
64    // Get the Direct3D 11.1 API device and context interfaces.
65    DX::ThrowIfFailed(
66        device.As(&m_d3dDevice)
67        );
68
69    DX::ThrowIfFailed(
70        context.As(&m_d3dContext)
71        );
72}
73
74// Allocate all memory resources that depend on the window size.
75void Direct3DBase::CreateWindowSizeDependentResources()
76{
77    // Create a descriptor for the render target buffer.
78    CD3D11_TEXTURE2D_DESC renderTargetDesc(
79        DXGI_FORMAT_B8G8R8A8_UNORM,
80        static_cast<UINT>(m_renderTargetSize.Width),
81        static_cast<UINT>(m_renderTargetSize.Height),
82        1,
83        1,
84        D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE
85        );
86    renderTargetDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
87
88    // Allocate a 2-D surface as the render target buffer.
89    DX::ThrowIfFailed(
90        m_d3dDevice->CreateTexture2D(
91            &renderTargetDesc,
92            nullptr,
93            &m_renderTarget
94            )
95        );
96
97    DX::ThrowIfFailed(
98        m_d3dDevice->CreateRenderTargetView(
99            m_renderTarget.Get(),
100            nullptr,
101            &m_renderTargetView
102            )
103        );
104
105    // Create a depth stencil view.
106    CD3D11_TEXTURE2D_DESC depthStencilDesc(
107        DXGI_FORMAT_D24_UNORM_S8_UINT,
108        static_cast<UINT>(m_renderTargetSize.Width),
109        static_cast<UINT>(m_renderTargetSize.Height),
110        1,
111        1,
112        D3D11_BIND_DEPTH_STENCIL
113        );
114
115    ComPtr<ID3D11Texture2D> depthStencil;
116    DX::ThrowIfFailed(
117        m_d3dDevice->CreateTexture2D(
118            &depthStencilDesc,
119            nullptr,
120            &depthStencil
121            )
122        );
123
124    CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
125    DX::ThrowIfFailed(
126        m_d3dDevice->CreateDepthStencilView(
127            depthStencil.Get(),
128            &depthStencilViewDesc,
129            &m_depthStencilView
130            )
131        );
132
133    // Set the rendering viewport to target the entire window.
134    CD3D11_VIEWPORT viewport(
135        0.0f,
136        0.0f,
137        m_renderTargetSize.Width,
138        m_renderTargetSize.Height
139        );
140
141    m_d3dContext->RSSetViewports(1, &viewport);
142}
143
144void Direct3DBase::UpdateForRenderResolutionChange(float width, float height)
145{
146    m_renderTargetSize.Width = width;
147    m_renderTargetSize.Height = height;
148
149    ID3D11RenderTargetView* nullViews[] = {nullptr};
150    m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
151    m_renderTarget = nullptr;
152    m_renderTargetView = nullptr;
153    m_depthStencilView = nullptr;
154    m_d3dContext->Flush();
155    CreateWindowSizeDependentResources();
156}
157
158void Direct3DBase::UpdateForWindowSizeChange(float width, float height)
159{
160    m_windowBounds.Width  = width;
161    m_windowBounds.Height = height;
162}
163