#include "pch.h" #include "CubeRenderer.h" using namespace DirectX; using namespace Microsoft::WRL; using namespace Windows::Foundation; using namespace Windows::UI::Core; CubeRenderer::CubeRenderer() : m_loadingComplete(false) , m_indexCount(0) { } void CubeRenderer::CreateDeviceResources() { Direct3DBase::CreateDeviceResources(); auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso"); auto loadPSTask = DX::ReadDataAsync("SimplePixelShader.cso"); auto createVSTask = loadVSTask.then([this](Platform::Array ^ fileData) { DX::ThrowIfFailed(m_d3dDevice->CreateVertexShader( fileData->Data, fileData->Length, nullptr, &m_vertexShader)); const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; DX::ThrowIfFailed(m_d3dDevice->CreateInputLayout( vertexDesc, ARRAYSIZE(vertexDesc), fileData->Data, fileData->Length, &m_inputLayout)); }); auto createPSTask = loadPSTask.then([this](Platform::Array ^ fileData) { DX::ThrowIfFailed(m_d3dDevice->CreatePixelShader( fileData->Data, fileData->Length, nullptr, &m_pixelShader)); CD3D11_BUFFER_DESC constantBufferDesc( sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER); DX::ThrowIfFailed(m_d3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &m_constantBuffer)); }); auto createCubeTask = (createPSTask && createVSTask).then([this]() { VertexPositionColor cubeVertices[] = { { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, 0.0f) }, { XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f) }, { XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f) }, { XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT3(0.0f, 1.0f, 1.0f) }, { XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f) }, { XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT3(1.0f, 0.0f, 1.0f) }, { XMFLOAT3(0.5f, 0.5f, -0.5f), XMFLOAT3(1.0f, 1.0f, 0.0f) }, { XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT3(1.0f, 1.0f, 1.0f) }, }; D3D11_SUBRESOURCE_DATA vertexBufferData = { 0 }; vertexBufferData.pSysMem = cubeVertices; vertexBufferData.SysMemPitch = 0; vertexBufferData.SysMemSlicePitch = 0; CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER); DX::ThrowIfFailed(m_d3dDevice->CreateBuffer( &vertexBufferDesc, &vertexBufferData, &m_vertexBuffer)); unsigned short cubeIndices[] = { 0, 2, 1, // -x 1, 2, 3, 4, 5, 6, // +x 5, 7, 6, 0, 1, 5, // -y 0, 5, 4, 2, 6, 7, // +y 2, 7, 3, 0, 4, 6, // -z 0, 6, 2, 1, 3, 7, // +z 1, 7, 5, }; m_indexCount = ARRAYSIZE(cubeIndices); D3D11_SUBRESOURCE_DATA indexBufferData = { 0 }; indexBufferData.pSysMem = cubeIndices; indexBufferData.SysMemPitch = 0; indexBufferData.SysMemSlicePitch = 0; CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER); DX::ThrowIfFailed(m_d3dDevice->CreateBuffer( &indexBufferDesc, &indexBufferData, &m_indexBuffer)); }); createCubeTask.then([this]() { m_loadingComplete = true; }); } void CubeRenderer::CreateWindowSizeDependentResources() { Direct3DBase::CreateWindowSizeDependentResources(); float aspectRatio = m_windowBounds.Width / m_windowBounds.Height; float fovAngleY = 70.0f * XM_PI / 180.0f; if (aspectRatio < 1.0f) { fovAngleY /= aspectRatio; } // Note that the m_orientationTransform3D matrix is post-multiplied here // in order to correctly orient the scene to match the display orientation. // This post-multiplication step is required for any draw calls that are // made to the swap chain render target. For draw calls to other targets, // this transform should not be applied. XMStoreFloat4x4( &m_constantBufferData.projection, XMMatrixTranspose(XMMatrixMultiply( XMMatrixPerspectiveFovRH(fovAngleY, aspectRatio, 0.01f, 100.0f), XMLoadFloat4x4(&m_orientationTransform3D)))); } void CubeRenderer::Update(float timeTotal, float timeDelta) { (void)timeDelta; // Unused parameter. XMVECTOR eye = XMVectorSet(0.0f, 0.7f, 1.5f, 0.0f); XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f); XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up))); XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(timeTotal * XM_PIDIV4))); } void CubeRenderer::Render() { const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f }; m_d3dContext->ClearRenderTargetView(m_renderTargetView.Get(), midnightBlue); m_d3dContext->ClearDepthStencilView(m_depthStencilView.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0); // Only draw the cube once it is loaded (loading is asynchronous). if (!m_loadingComplete) { return; } m_d3dContext->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(), m_depthStencilView.Get()); m_d3dContext->UpdateSubresource(m_constantBuffer.Get(), 0, NULL, &m_constantBufferData, 0, 0); UINT stride = sizeof(VertexPositionColor); UINT offset = 0; m_d3dContext->IASetVertexBuffers(0, 1, m_vertexBuffer.GetAddressOf(), &stride, &offset); m_d3dContext->IASetIndexBuffer(m_indexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0); m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_d3dContext->IASetInputLayout(m_inputLayout.Get()); m_d3dContext->VSSetShader(m_vertexShader.Get(), nullptr, 0); m_d3dContext->VSSetConstantBuffers(0, 1, m_constantBuffer.GetAddressOf()); m_d3dContext->PSSetShader(m_pixelShader.Get(), nullptr, 0); m_d3dContext->DrawIndexed(m_indexCount, 0, 0); }