#include "SDLmain_WinRT_common.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; // 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 ); }