1 #include "pch.h"
2 #include "QuadRenderer.h"
3
4 using namespace DirectX;
5 using namespace Microsoft::WRL;
6 using namespace Windows::Foundation;
7 using namespace Windows::UI::Core;
8
QuadRenderer()9 QuadRenderer::QuadRenderer() :
10 m_loadingComplete(false),
11 m_indexCount(0)
12 {
13 }
14
CreateTextureFromByte(byte * buffer,int width,int height)15 void QuadRenderer::CreateTextureFromByte(byte* buffer,int width,int height)
16 {
17 int pixelSize = 4;
18
19 if (m_Texture.Get() == nullptr)
20 {
21 CD3D11_TEXTURE2D_DESC textureDesc(
22 DXGI_FORMAT_B8G8R8A8_UNORM, // format
23 static_cast<UINT>(width), // width
24 static_cast<UINT>(height), // height
25 1, // arraySize
26 1, // mipLevels
27 D3D11_BIND_SHADER_RESOURCE, // bindFlags
28 D3D11_USAGE_DYNAMIC, // usage
29 D3D11_CPU_ACCESS_WRITE, // cpuaccessFlags
30 1, // sampleCount
31 0, // sampleQuality
32 0 // miscFlags
33 );
34
35 D3D11_SUBRESOURCE_DATA data;
36 data.pSysMem = buffer;
37 data.SysMemPitch = pixelSize*width;
38 data.SysMemSlicePitch = pixelSize*width*height;
39
40 DX::ThrowIfFailed(
41 m_d3dDevice->CreateTexture2D(
42 &textureDesc,
43 &data,
44 m_Texture.ReleaseAndGetAddressOf()
45 )
46 );
47
48 m_d3dDevice->CreateShaderResourceView(m_Texture.Get(), NULL, m_SRV.ReleaseAndGetAddressOf());
49 D3D11_SAMPLER_DESC sampDesc;
50 ZeroMemory(&sampDesc, sizeof(sampDesc));
51 sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
52 sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
53 sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
54 sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
55 sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
56 sampDesc.MinLOD = 0;
57 sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
58 m_d3dDevice->CreateSamplerState(&sampDesc, m_QuadsTexSamplerState.ReleaseAndGetAddressOf());
59 }
60 else
61 {
62 int nRowSpan = width * pixelSize;
63 D3D11_MAPPED_SUBRESOURCE mappedResource;
64 HRESULT hr = m_d3dContext->Map(m_Texture.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
65 BYTE* mappedData = static_cast<BYTE*>(mappedResource.pData);
66
67 for (int i = 0; i < height; ++i)
68 {
69 memcpy(mappedData + (i*mappedResource.RowPitch), buffer + (i*nRowSpan), nRowSpan);
70 }
71
72 m_d3dContext->Unmap(m_Texture.Get(), 0);
73 }
74 }
75
CreateDeviceResources()76 void QuadRenderer::CreateDeviceResources()
77 {
78 Direct3DBase::CreateDeviceResources();
79 D3D11_BLEND_DESC blendDesc;
80 ZeroMemory( &blendDesc, sizeof(blendDesc) );
81
82 D3D11_RENDER_TARGET_BLEND_DESC rtbd;
83 ZeroMemory( &rtbd, sizeof(rtbd) );
84
85 rtbd.BlendEnable = TRUE;
86 rtbd.SrcBlend = D3D11_BLEND_SRC_ALPHA;
87 rtbd.DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
88 rtbd.BlendOp = D3D11_BLEND_OP_ADD;
89 rtbd.SrcBlendAlpha = D3D11_BLEND_ONE;
90 rtbd.DestBlendAlpha = D3D11_BLEND_ZERO;
91 rtbd.BlendOpAlpha = D3D11_BLEND_OP_ADD;
92 rtbd.RenderTargetWriteMask = 0x0f;
93
94 blendDesc.AlphaToCoverageEnable = false;
95 blendDesc.RenderTarget[0] = rtbd;
96
97 m_d3dDevice->CreateBlendState(&blendDesc, &m_Transparency);
98
99 D3D11_RASTERIZER_DESC cmdesc;
100 ZeroMemory(&cmdesc, sizeof(D3D11_RASTERIZER_DESC));
101
102 cmdesc.FillMode = D3D11_FILL_SOLID;
103 cmdesc.CullMode = D3D11_CULL_BACK;
104 cmdesc.DepthClipEnable = TRUE;
105
106 cmdesc.FrontCounterClockwise = true;
107 m_d3dDevice->CreateRasterizerState(&cmdesc, &CCWcullMode);
108
109 cmdesc.FrontCounterClockwise = false;
110 m_d3dDevice->CreateRasterizerState(&cmdesc, &CWcullMode);
111
112 auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso");
113 auto loadPSTask = DX::ReadDataAsync("SimplePixelShader.cso");
114 auto createVSTask = loadVSTask.then([this](Platform::Array<byte>^ fileData)
115 {
116 DX::ThrowIfFailed(
117 m_d3dDevice->CreateVertexShader(
118 fileData->Data,
119 fileData->Length,
120 nullptr,
121 &m_vertexShader
122 )
123 );
124
125 const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
126 {
127 { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
128 { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
129 };
130
131 DX::ThrowIfFailed(
132 m_d3dDevice->CreateInputLayout(
133 vertexDesc,
134 ARRAYSIZE(vertexDesc),
135 fileData->Data,
136 fileData->Length,
137 &m_inputLayout
138 )
139 );
140 });
141
142 auto createPSTask = loadPSTask.then([this](Platform::Array<byte>^ fileData)
143 {
144 DX::ThrowIfFailed(
145 m_d3dDevice->CreatePixelShader(
146 fileData->Data,
147 fileData->Length,
148 nullptr,
149 &m_pixelShader
150 )
151 );
152
153 CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
154 DX::ThrowIfFailed(
155 m_d3dDevice->CreateBuffer(
156 &constantBufferDesc,
157 nullptr,
158 &m_constantBuffer
159 )
160 );
161 });
162
163 auto createCubeTask = (createPSTask && createVSTask).then([this] ()
164 {
165 Vertex v[] =
166 {
167 Vertex(-1.0f, -1.0f, 1.0f, 1.0f, 1.0f),
168 Vertex(1.0f, -1.0f, 1.0f, 0.0f, 1.0f),
169 Vertex(1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
170 Vertex(-1.0f, 1.0f, 1.0f, 1.0f, 0.0f)
171 };
172
173 D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
174 vertexBufferData.pSysMem = v;
175 vertexBufferData.SysMemPitch = 0;
176 vertexBufferData.SysMemSlicePitch = 0;
177 CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(v), D3D11_BIND_VERTEX_BUFFER);
178 DX::ThrowIfFailed(
179 m_d3dDevice->CreateBuffer(
180 &vertexBufferDesc,
181 &vertexBufferData,
182 &m_vertexBuffer
183 )
184 );
185
186 DWORD indices[] =
187 {
188 // Front Face
189 0, 2, 1,
190 0, 3, 2,
191
192 };
193
194 m_indexCount = ARRAYSIZE(indices);
195
196 D3D11_SUBRESOURCE_DATA indexBufferData = {0};
197 indexBufferData.pSysMem = indices;
198 indexBufferData.SysMemPitch = 0;
199 indexBufferData.SysMemSlicePitch = 0;
200 CD3D11_BUFFER_DESC indexBufferDesc(sizeof(indices), D3D11_BIND_INDEX_BUFFER);
201 DX::ThrowIfFailed(
202 m_d3dDevice->CreateBuffer(
203 &indexBufferDesc,
204 &indexBufferData,
205 &m_indexBuffer
206 )
207 );
208 });
209
210 createCubeTask.then([this] ()
211 {
212 m_loadingComplete = true;
213 });
214 }
215
CreateWindowSizeDependentResources()216 void QuadRenderer::CreateWindowSizeDependentResources()
217 {
218 Direct3DBase::CreateWindowSizeDependentResources();
219
220 float aspectRatio = m_windowBounds.Width / m_windowBounds.Height;
221 float fovAngleY = 60.0f * (XM_PI / 180.0f);
222
223 if (aspectRatio < 1.0f)
224 {
225 fovAngleY /= aspectRatio;
226 }
227
228 XMStoreFloat4x4(
229 &m_constantBufferData.projection,
230 XMMatrixTranspose(
231 XMMatrixPerspectiveFovRH(
232 fovAngleY,
233 aspectRatio,
234 0.01f,
235 100.0f
236 )
237 )
238 );
239 }
240
Update(float timeTotal,float timeDelta)241 void QuadRenderer::Update(float timeTotal, float timeDelta)
242 {
243 (void) timeDelta; // Unused parameter.
244
245 XMVECTOR X = XMVectorSet(0.0f, 0.0f, .3f, 0.0f);
246 XMVECTOR Y = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
247 XMVECTOR Z = XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f);
248
249 XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtLH(X, Y, Z)));
250 XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(timeTotal * XM_PIDIV4)));
251 }
252
Render()253 void QuadRenderer::Render()
254 {
255 Render(m_renderTargetView, m_depthStencilView);
256 }
257
Render(Microsoft::WRL::ComPtr<ID3D11RenderTargetView> renderTargetView,Microsoft::WRL::ComPtr<ID3D11DepthStencilView> depthStencilView)258 void QuadRenderer::Render(Microsoft::WRL::ComPtr<ID3D11RenderTargetView> renderTargetView, Microsoft::WRL::ComPtr<ID3D11DepthStencilView> depthStencilView)
259 {
260 const float black[] = {0, 0, 0, 1.0 };
261
262 m_d3dContext->ClearRenderTargetView(
263 renderTargetView.Get(),
264 black
265 );
266
267 m_d3dContext->ClearDepthStencilView(
268 depthStencilView.Get(),
269 D3D11_CLEAR_DEPTH,
270 1.0f,
271 0
272 );
273
274 if (m_SRV && m_loadingComplete) // Only draw the cube once it is loaded (loading is asynchronous).
275 {
276 m_d3dContext->OMSetRenderTargets(
277 1,
278 renderTargetView.GetAddressOf(),
279 depthStencilView.Get()
280 );
281
282 m_d3dContext->UpdateSubresource(
283 m_constantBuffer.Get(),
284 0,
285 NULL,
286 &m_constantBufferData,
287 0,
288 0
289 );
290
291 UINT stride = sizeof(Vertex);
292 UINT offset = 0;
293
294 m_d3dContext->IASetVertexBuffers(
295 0,
296 1,
297 m_vertexBuffer.GetAddressOf(),
298 &stride,
299 &offset
300 );
301
302 m_d3dContext->IASetIndexBuffer(
303 m_indexBuffer.Get(),
304 DXGI_FORMAT_R32_UINT,
305 0
306 );
307
308 m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
309 m_d3dContext->IASetInputLayout(m_inputLayout.Get());
310
311 m_d3dContext->VSSetShader(
312 m_vertexShader.Get(),
313 nullptr,
314 0
315 );
316
317 m_d3dContext->VSSetConstantBuffers(
318 0,
319 1,
320 m_constantBuffer.GetAddressOf()
321 );
322
323 m_d3dContext->PSSetShader(
324 m_pixelShader.Get(),
325 nullptr,
326 0
327 );
328
329 m_d3dContext->PSSetShaderResources(0, 1, m_SRV.GetAddressOf());
330 m_d3dContext->PSSetSamplers(0, 1, m_QuadsTexSamplerState.GetAddressOf());
331 m_d3dContext->OMSetBlendState(m_Transparency.Get(), nullptr, 0xffffffff);
332 m_d3dContext->RSSetState(CCWcullMode.Get());
333
334 m_d3dContext->DrawIndexed(
335 m_indexCount,
336 0,
337 0
338 );
339 }
340 }