• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }