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