-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSwapChain.cpp
More file actions
117 lines (97 loc) · 4.3 KB
/
SwapChain.cpp
File metadata and controls
117 lines (97 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "SwapChain.h"
SwapChain::SwapChain(HWND hWnd, UINT width, UINT height, RenderSystem* renderSystem)
{
mRenderSystem = renderSystem;
DXGI_SWAP_CHAIN_DESC desc;
// Clear out the memory for the struct to use
ZeroMemory(&desc, sizeof(DXGI_SWAP_CHAIN_DESC));
// TODO: Parameterize the descriptor from user input
desc.BufferCount = 1; // one back buffer
desc.BufferDesc.Width = width;
desc.BufferDesc.Height = height;
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
desc.BufferDesc.RefreshRate.Numerator = 60;
desc.BufferDesc.RefreshRate.Denominator = 1;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
desc.OutputWindow = hWnd; // the window to be used
desc.SampleDesc.Count = 1; // nr. of multisamples (for anti-aliasing)
desc.SampleDesc.Quality = 0;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
/*
* DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
* Set this flag to enable an application to switch modes by calling IDXGISwapChain::ResizeTarget.
* When switching from windowed to full-screen mode, the display mode (or monitor resolution)
* will be changed to match the dimensions of the application window.
*/
desc.Windowed = TRUE; // windowed / full-screen mode
// Create the swap chain for the window indicated by HWND parameter
HRESULT hr = mRenderSystem->mDxgiFactory->CreateSwapChain(mRenderSystem->mD3DDevice, &desc, &mSwapChain);
if (FAILED(hr))
throw std::exception("SwapChain not created successfully");
reloadBuffers(width, height);
}
SwapChain::~SwapChain()
{
mRtv->Release();
mDsv->Release();
mSwapChain->Release();
}
// ----------------------------
// Used to correctly render the vertices
// depending on the position of the camera
// (hide pixels that are not visible even if they were rendered last?)
// ----------------------------
void SwapChain::reloadBuffers(UINT width, UINT height)
{
ID3D11Device* device = mRenderSystem->mD3DDevice;
// Get the backBuffer color and create its render target view
ID3D11Texture2D* backBuffer = nullptr;
/*
* __uuidof Operator -> Retrieves the GUID attached to the expression.
* A GUID identifies an object such as a COM interfaces, or a COM class object, or a manager entry-point vector (EPV)
* A GUID is a 128-bit value
*/
HRESULT hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer);
if (FAILED(hr)) throw std::exception("SwapChain not created successfully");
// The render target is like a blank canvas where we draw the shapes
// (in this case the canvas would be the back buffer of the swap chain)
hr = device->CreateRenderTargetView(backBuffer, nullptr, &mRtv);
backBuffer->Release();
if (FAILED(hr)) throw std::exception("SwapChain not created successfully");
D3D11_TEXTURE2D_DESC tex_desc = {};
tex_desc.Width = width;
tex_desc.Height = height;
tex_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
tex_desc.Usage = D3D11_USAGE_DEFAULT;
tex_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
tex_desc.MipLevels = 1;
tex_desc.SampleDesc.Count = 1;
tex_desc.SampleDesc.Quality = 0;
tex_desc.MiscFlags = 0;
tex_desc.ArraySize = 1;
tex_desc.CPUAccessFlags = 0;
hr = device->CreateTexture2D(&tex_desc, nullptr, &backBuffer);
if (FAILED(hr)) throw std::exception("SwapChain not created successfully in realoadBuffers()");
hr = device->CreateDepthStencilView(backBuffer, nullptr, &mDsv);
if (FAILED(hr)) throw std::exception("SwapChain not created successfully in realoadBuffers()");
backBuffer->Release();
}
void SwapChain::setFullScreen(bool fullscreen, unsigned int width, unsigned int height)
{
this->resize(width, height);
mSwapChain->SetFullscreenState(fullscreen, nullptr);
}
void SwapChain::resize(unsigned int width, unsigned int height)
{
if (mRtv) mRtv->Release();
if (mDsv) mDsv->Release();
this->mSwapChain->ResizeBuffers(
1, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0
);
this->reloadBuffers(width, height);
}
bool SwapChain::present(bool vsync)
{
mSwapChain->Present(vsync, NULL);
return true;
}