Advertisement
Guest User

Untitled

a guest
Jul 30th, 2015
410
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.80 KB | None | 0 0
  1. #include "pch.h"
  2. #include "Sample3DSceneRenderer.h"
  3.  
  4. #include "..\Common\DirectXHelper.h"
  5. #include <ppltasks.h>
  6. #include <synchapi.h>
  7.  
  8. using namespace DX12;
  9.  
  10. using namespace Concurrency;
  11. using namespace DirectX;
  12. using namespace Microsoft::WRL;
  13. using namespace Windows::Foundation;
  14. using namespace Windows::Storage;
  15.  
  16. // Indices into the application state map.
  17. Platform::String^ AngleKey = "Angle";
  18. Platform::String^ TrackingKey = "Tracking";
  19.  
  20. // Loads vertex and pixel shaders from files and instantiates the cube geometry.
  21. Sample3DSceneRenderer::Sample3DSceneRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
  22.     m_loadingComplete(false),
  23.     m_radiansPerSecond(XM_PIDIV4)// rotate 45 degrees per second
  24.     m_angle(0),
  25.     m_tracking(false),
  26.     m_mappedConstantBuffer(nullptr),
  27.     m_deviceResources(deviceResources)
  28. {
  29.     LoadState();
  30.     ZeroMemory(&m_constantBufferData, sizeof(m_constantBufferData));
  31.  
  32.     CreateDeviceDependentResources();
  33.     CreateWindowSizeDependentResources();
  34. }
  35.  
  36. Sample3DSceneRenderer::~Sample3DSceneRenderer()
  37. {
  38.     m_constantBuffer->Unmap(0, nullptr);
  39.     m_mappedConstantBuffer = nullptr;
  40. }
  41.  
  42. void Sample3DSceneRenderer::CreateDeviceDependentResources()
  43. {
  44.     auto d3dDevice = m_deviceResources->GetD3DDevice();
  45.  
  46.     // Create a root signature with a single constant buffer slot.
  47.     {
  48.         CD3DX12_DESCRIPTOR_RANGE range;
  49.         CD3DX12_ROOT_PARAMETER parameter;
  50.  
  51.         range.Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
  52.         parameter.InitAsDescriptorTable(1, &range, D3D12_SHADER_VISIBILITY_VERTEX);
  53.  
  54.         D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags =
  55.             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | // Only the input assembler stage needs access to the constant buffer.
  56.             D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
  57.             D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
  58.             D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
  59.             D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;
  60.  
  61.         CD3DX12_ROOT_SIGNATURE_DESC descRootSignature;
  62.         descRootSignature.Init(1, &parameter, 0, nullptr, rootSignatureFlags);
  63.  
  64.         ComPtr<ID3DBlob> pSignature;
  65.         ComPtr<ID3DBlob> pError;
  66.         DX::ThrowIfFailed(D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, pSignature.GetAddressOf(), pError.GetAddressOf()));
  67.         DX::ThrowIfFailed(d3dDevice->CreateRootSignature(0, pSignature->GetBufferPointer(), pSignature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
  68.     }
  69.  
  70.     // Load shaders asynchronously.
  71.     auto createVSTask = DX::ReadDataAsync(L"SampleVertexShader.cso").then([this](std::vector<byte>& fileData) {
  72.         m_vertexShader = fileData;
  73.     });
  74.  
  75.     auto createPSTask = DX::ReadDataAsync(L"SamplePixelShader.cso").then([this](std::vector<byte>& fileData) {
  76.         m_pixelShader = fileData;
  77.     });
  78.  
  79.     // Create the pipeline state once the shaders are loaded.
  80.     auto createPipelineStateTask = (createPSTask && createVSTask).then([this]() {
  81.  
  82.         static const D3D12_INPUT_ELEMENT_DESC inputLayout[] =
  83.         {
  84.             { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
  85.             { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
  86.         };
  87.  
  88.         D3D12_GRAPHICS_PIPELINE_STATE_DESC state = {};
  89.         state.InputLayout = { inputLayout, _countof(inputLayout) };
  90.         state.pRootSignature = m_rootSignature.Get();
  91.         state.VS = { &m_vertexShader[0], m_vertexShader.size() };
  92.         state.PS = { &m_pixelShader[0], m_pixelShader.size() };
  93.         state.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
  94.         state.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
  95.         state.DepthStencilState.DepthEnable = FALSE;
  96.         state.DepthStencilState.StencilEnable = FALSE;
  97.         state.SampleMask = UINT_MAX;
  98.         state.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
  99.         state.NumRenderTargets = 1;
  100.         state.RTVFormats[0] = DXGI_FORMAT_B8G8R8A8_UNORM;
  101.         state.SampleDesc.Count = 1;
  102.  
  103.         DX::ThrowIfFailed(m_deviceResources->GetD3DDevice()->CreateGraphicsPipelineState(&state, IID_PPV_ARGS(&m_pipelineState)));
  104.  
  105.         // Shader data can be deleted once the pipeline state is created.
  106.         m_vertexShader.clear();
  107.         m_pixelShader.clear();
  108.     });
  109.  
  110.     // Create and upload cube geometry resources to the GPU.
  111.     auto createAssetsTask = createPipelineStateTask.then([this]() {
  112.         auto d3dDevice = m_deviceResources->GetD3DDevice();
  113.  
  114.         // Create a command list.
  115.         DX::ThrowIfFailed(d3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_deviceResources->GetCommandAllocator(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList)));
  116.  
  117.         // Cube vertices. Each vertex has a position and a color.
  118.         VertexPositionColor cubeVertices[] =
  119.         {
  120.             { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, 0.0f) },
  121.             { XMFLOAT3(-0.5f, -0.5f,  0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f) },
  122.             { XMFLOAT3(-0.5f,  0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f) },
  123.             { XMFLOAT3(-0.5f,  0.5f,  0.5f), XMFLOAT3(0.0f, 1.0f, 1.0f) },
  124.             { XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f) },
  125.             { XMFLOAT3(0.5f, -0.5f,  0.5f), XMFLOAT3(1.0f, 0.0f, 1.0f) },
  126.             { XMFLOAT3(0.5f,  0.5f, -0.5f), XMFLOAT3(1.0f, 1.0f, 0.0f) },
  127.             { XMFLOAT3(0.5f,  0.5f,  0.5f), XMFLOAT3(1.0f, 1.0f, 1.0f) },
  128.         };
  129.  
  130.         const UINT vertexBufferSize = sizeof(cubeVertices);
  131.  
  132.         // Create the vertex buffer resource in the GPU's default heap and copy vertex data into it using the upload heap.
  133.         // The upload resource must not be released until after the GPU has finished using it.
  134.         Microsoft::WRL::ComPtr<ID3D12Resource> vertexBufferUpload;
  135.  
  136.         CD3DX12_HEAP_PROPERTIES defaultHeapProperties(D3D12_HEAP_TYPE_DEFAULT);
  137.         CD3DX12_RESOURCE_DESC vertexBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize);
  138.         DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
  139.             &defaultHeapProperties,
  140.             D3D12_HEAP_FLAG_NONE,
  141.             &vertexBufferDesc,
  142.             D3D12_RESOURCE_STATE_COPY_DEST,
  143.             nullptr,
  144.             IID_PPV_ARGS(&m_vertexBuffer)));
  145.  
  146.         CD3DX12_HEAP_PROPERTIES uploadHeapProperties(D3D12_HEAP_TYPE_UPLOAD);
  147.         DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
  148.             &uploadHeapProperties,
  149.             D3D12_HEAP_FLAG_NONE,
  150.             &vertexBufferDesc,
  151.             D3D12_RESOURCE_STATE_GENERIC_READ,
  152.             nullptr,
  153.             IID_PPV_ARGS(&vertexBufferUpload)));
  154.  
  155.         m_vertexBuffer->SetName(L"Vertex Buffer Resource");
  156.         vertexBufferUpload->SetName(L"Vertex Buffer Upload Resource");
  157.  
  158.         // Upload the vertex buffer to the GPU.
  159.         {
  160.             D3D12_SUBRESOURCE_DATA vertexData = {};
  161.             vertexData.pData = reinterpret_cast<BYTE*>(cubeVertices);
  162.             vertexData.RowPitch = vertexBufferSize;
  163.             vertexData.SlicePitch = vertexData.RowPitch;
  164.  
  165.             UpdateSubresources(m_commandList.Get(), m_vertexBuffer.Get(), vertexBufferUpload.Get(), 0, 0, 1, &vertexData);
  166.  
  167.             CD3DX12_RESOURCE_BARRIER vertexBufferResourceBarrier =
  168.                 CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
  169.             m_commandList->ResourceBarrier(1, &vertexBufferResourceBarrier);
  170.         }
  171.  
  172.         // Load mesh indices. Each trio of indices represents a triangle to be rendered on the screen.
  173.         // For example: 0,2,1 means that the vertices with indexes 0, 2 and 1 from the vertex buffer compose the
  174.         // first triangle of this mesh.
  175.         unsigned short cubeIndices[] =
  176.         {
  177.             0, 2, 1, // -x
  178.             1, 2, 3,
  179.  
  180.             4, 5, 6, // +x
  181.             5, 7, 6,
  182.  
  183.             0, 1, 5, // -y
  184.             0, 5, 4,
  185.  
  186.             2, 6, 7, // +y
  187.             2, 7, 3,
  188.  
  189.             0, 4, 6, // -z
  190.             0, 6, 2,
  191.  
  192.             1, 3, 7, // +z
  193.             1, 7, 5,
  194.         };
  195.  
  196.         const UINT indexBufferSize = sizeof(cubeIndices);
  197.  
  198.         // Create the index buffer resource in the GPU's default heap and copy index data into it using the upload heap.
  199.         // The upload resource must not be released until after the GPU has finished using it.
  200.         Microsoft::WRL::ComPtr<ID3D12Resource> indexBufferUpload;
  201.  
  202.         CD3DX12_RESOURCE_DESC indexBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(indexBufferSize);
  203.         DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
  204.             &defaultHeapProperties,
  205.             D3D12_HEAP_FLAG_NONE,
  206.             &indexBufferDesc,
  207.             D3D12_RESOURCE_STATE_COPY_DEST,
  208.             nullptr,
  209.             IID_PPV_ARGS(&m_indexBuffer)));
  210.  
  211.         DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
  212.             &uploadHeapProperties,
  213.             D3D12_HEAP_FLAG_NONE,
  214.             &indexBufferDesc,
  215.             D3D12_RESOURCE_STATE_GENERIC_READ,
  216.             nullptr,
  217.             IID_PPV_ARGS(&indexBufferUpload)));
  218.  
  219.         m_indexBuffer->SetName(L"Index Buffer Resource");
  220.         indexBufferUpload->SetName(L"Index Buffer Upload Resource");
  221.  
  222.         // Upload the index buffer to the GPU.
  223.         {
  224.             D3D12_SUBRESOURCE_DATA indexData = {};
  225.             indexData.pData = reinterpret_cast<BYTE*>(cubeIndices);
  226.             indexData.RowPitch = indexBufferSize;
  227.             indexData.SlicePitch = indexData.RowPitch;
  228.  
  229.             UpdateSubresources(m_commandList.Get(), m_indexBuffer.Get(), indexBufferUpload.Get(), 0, 0, 1, &indexData);
  230.  
  231.             CD3DX12_RESOURCE_BARRIER indexBufferResourceBarrier =
  232.                 CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
  233.             m_commandList->ResourceBarrier(1, &indexBufferResourceBarrier);
  234.         }
  235.  
  236.         // Create a descriptor heap for the constant buffers.
  237.         {
  238.             D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
  239.             heapDesc.NumDescriptors = DX::c_frameCount;
  240.             heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
  241.             // This flag indicates that this descriptor heap can be bound to the pipeline and that descriptors contained in it can be referenced by a root table.
  242.             heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
  243.             DX::ThrowIfFailed(d3dDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_cbvHeap)));
  244.  
  245.             m_cbvHeap->SetName(L"Constant Buffer View Descriptor Heap");
  246.         }
  247.  
  248.         CD3DX12_RESOURCE_DESC constantBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(DX::c_frameCount * c_alignedConstantBufferSize);
  249.         DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
  250.             &uploadHeapProperties,
  251.             D3D12_HEAP_FLAG_NONE,
  252.             &constantBufferDesc,
  253.             D3D12_RESOURCE_STATE_GENERIC_READ,
  254.             nullptr,
  255.             IID_PPV_ARGS(&m_constantBuffer)));
  256.  
  257.         m_constantBuffer->SetName(L"Constant Buffer");
  258.  
  259.         // Create constant buffer views to access the upload buffer.
  260.         D3D12_GPU_VIRTUAL_ADDRESS cbvGpuAddress = m_constantBuffer->GetGPUVirtualAddress();
  261.         CD3DX12_CPU_DESCRIPTOR_HANDLE cbvCpuHandle(m_cbvHeap->GetCPUDescriptorHandleForHeapStart());
  262.         m_cbvDescriptorSize = d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
  263.  
  264.         for (int n = 0; n < DX::c_frameCount; n++)
  265.         {
  266.             D3D12_CONSTANT_BUFFER_VIEW_DESC desc;
  267.             desc.BufferLocation = cbvGpuAddress;
  268.             desc.SizeInBytes = c_alignedConstantBufferSize;
  269.             d3dDevice->CreateConstantBufferView(&desc, cbvCpuHandle);
  270.  
  271.             cbvGpuAddress += desc.SizeInBytes;
  272.             cbvCpuHandle.Offset(m_cbvDescriptorSize);
  273.         }
  274.  
  275.         // Map the constant buffers.
  276.         DX::ThrowIfFailed(m_constantBuffer->Map(0, nullptr, reinterpret_cast<void**>(&m_mappedConstantBuffer)));
  277.         ZeroMemory(m_mappedConstantBuffer, DX::c_frameCount * c_alignedConstantBufferSize);
  278.         // We don't unmap this until the app closes. Keeping things mapped for the lifetime of the resource is okay.
  279.  
  280.         // Close the command list and execute it to begin the vertex/index buffer copy into the GPU's default heap.
  281.         DX::ThrowIfFailed(m_commandList->Close());
  282.         ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
  283.         m_deviceResources->GetCommandQueue()->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
  284.  
  285.         // Create vertex/index buffer views.
  286.         m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
  287.         m_vertexBufferView.StrideInBytes = sizeof(VertexPositionColor);
  288.         m_vertexBufferView.SizeInBytes = sizeof(cubeVertices);
  289.  
  290.         m_indexBufferView.BufferLocation = m_indexBuffer->GetGPUVirtualAddress();
  291.         m_indexBufferView.SizeInBytes = sizeof(cubeIndices);
  292.         m_indexBufferView.Format = DXGI_FORMAT_R16_UINT;
  293.  
  294.         // Wait for the command list to finish executing; the vertex/index buffers need to be uploaded to the GPU before the upload resources go out of scope.
  295.         m_deviceResources->WaitForGpu();
  296.     });
  297.  
  298.     createAssetsTask.then([this]() {
  299.         m_loadingComplete = true;
  300.     });
  301. }
  302.  
  303. // Initializes view parameters when the window size changes.
  304. void Sample3DSceneRenderer::CreateWindowSizeDependentResources()
  305. {
  306.     Size outputSize = m_deviceResources->GetOutputSize();
  307.     float aspectRatio = outputSize.Width / outputSize.Height;
  308.     float fovAngleY = 70.0f * XM_PI / 180.0f;
  309.  
  310.     D3D12_VIEWPORT viewport = m_deviceResources->GetScreenViewport();
  311.     m_scissorRect = { 0, 0, static_cast<LONG>(viewport.Width), static_cast<LONG>(viewport.Height)};
  312.  
  313.     // This is a simple example of change that can be made when the app is in
  314.     // portrait or snapped view.
  315.     if (aspectRatio < 1.0f)
  316.     {
  317.         fovAngleY *= 2.0f;
  318.     }
  319.  
  320.     // Note that the OrientationTransform3D matrix is post-multiplied here
  321.     // in order to correctly orient the scene to match the display orientation.
  322.     // This post-multiplication step is required for any draw calls that are
  323.     // made to the swap chain render target. For draw calls to other targets,
  324.     // this transform should not be applied.
  325.  
  326.     // This sample makes use of a right-handed coordinate system using row-major matrices.
  327.     XMMATRIX perspectiveMatrix = XMMatrixPerspectiveFovRH(
  328.         fovAngleY,
  329.         aspectRatio,
  330.         0.01f,
  331.         100.0f
  332.         );
  333.  
  334.     XMFLOAT4X4 orientation = m_deviceResources->GetOrientationTransform3D();
  335.     XMMATRIX orientationMatrix = XMLoadFloat4x4(&orientation);
  336.  
  337.     XMStoreFloat4x4(
  338.         &m_constantBufferData.projection,
  339.         XMMatrixTranspose(perspectiveMatrix * orientationMatrix)
  340.         );
  341.  
  342.     // Eye is at (0,0.7,1.5), looking at point (0,-0.1,0) with the up-vector along the y-axis.
  343.     static const XMVECTORF32 eye = { 0.0f, 0.7f, 1.5f, 0.0f };
  344.     static const XMVECTORF32 at = { 0.0f, -0.1f, 0.0f, 0.0f };
  345.     static const XMVECTORF32 up = { 0.0f, 1.0f, 0.0f, 0.0f };
  346.  
  347.     XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));
  348. }
  349.  
  350. // Called once per frame, rotates the cube and calculates the model and view matrices.
  351. void Sample3DSceneRenderer::Update(DX::StepTimer const& timer)
  352. {
  353.     if (m_loadingComplete)
  354.     {
  355.         if (!m_tracking)
  356.         {
  357.             // Rotate the cube a small amount.
  358.             m_angle += static_cast<float>(timer.GetElapsedSeconds()) * m_radiansPerSecond;
  359.  
  360.             Rotate(m_angle);
  361.         }
  362.  
  363.         // Update the constant buffer resource.
  364.         UINT8* destination = m_mappedConstantBuffer + (m_deviceResources->GetCurrentFrameIndex() * c_alignedConstantBufferSize);
  365.         memcpy(destination, &m_constantBufferData, sizeof(m_constantBufferData));
  366.     }
  367. }
  368.  
  369. // Saves the current state of the renderer.
  370. void Sample3DSceneRenderer::SaveState()
  371. {
  372.     auto state = ApplicationData::Current->LocalSettings->Values;
  373.  
  374.     if (state->HasKey(AngleKey))
  375.     {
  376.         state->Remove(AngleKey);
  377.     }
  378.     if (state->HasKey(TrackingKey))
  379.     {
  380.         state->Remove(TrackingKey);
  381.     }
  382.  
  383.     state->Insert(AngleKey, PropertyValue::CreateSingle(m_angle));
  384.     state->Insert(TrackingKey, PropertyValue::CreateBoolean(m_tracking));
  385. }
  386.  
  387. // Restores the previous state of the renderer.
  388. void Sample3DSceneRenderer::LoadState()
  389. {
  390.     auto state = ApplicationData::Current->LocalSettings->Values;
  391.     if (state->HasKey(AngleKey))
  392.     {
  393.         m_angle = safe_cast<IPropertyValue^>(state->Lookup(AngleKey))->GetSingle();
  394.         state->Remove(AngleKey);
  395.     }
  396.     if (state->HasKey(TrackingKey))
  397.     {
  398.         m_tracking = safe_cast<IPropertyValue^>(state->Lookup(TrackingKey))->GetBoolean();
  399.         state->Remove(TrackingKey);
  400.     }
  401. }
  402.  
  403. // Rotate the 3D cube model a set amount of radians.
  404. void Sample3DSceneRenderer::Rotate(float radians)
  405. {
  406.     // Prepare to pass the updated model matrix to the shader.
  407.     XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(radians)));
  408. }
  409.  
  410. void Sample3DSceneRenderer::StartTracking()
  411. {
  412.     m_tracking = true;
  413. }
  414.  
  415. // When tracking, the 3D cube can be rotated around its Y axis by tracking pointer position relative to the output screen width.
  416. void Sample3DSceneRenderer::TrackingUpdate(float positionX)
  417. {
  418.     if (m_tracking)
  419.     {
  420.         float radians = XM_2PI * 2.0f * positionX / m_deviceResources->GetOutputSize().Width;
  421.         Rotate(radians);
  422.     }
  423. }
  424.  
  425. void Sample3DSceneRenderer::StopTracking()
  426. {
  427.     m_tracking = false;
  428. }
  429.  
  430. // Renders one frame using the vertex and pixel shaders.
  431. bool Sample3DSceneRenderer::Render()
  432. {
  433.     // Loading is asynchronous. Only draw geometry after it's loaded.
  434.     if (!m_loadingComplete)
  435.     {
  436.         return false;
  437.     }
  438.  
  439.     DX::ThrowIfFailed(m_deviceResources->GetCommandAllocator()->Reset());
  440.  
  441.     // The command list can be reset anytime after ExecuteCommandList() is called.
  442.     DX::ThrowIfFailed(m_commandList->Reset(m_deviceResources->GetCommandAllocator(), m_pipelineState.Get()));
  443.  
  444.     PIXBeginEvent(m_commandList.Get(), 0, L"Draw the cube");
  445.     {
  446.         // Set the graphics root signature and descriptor heaps to be used by this frame.
  447.         m_commandList->SetGraphicsRootSignature(m_rootSignature.Get());
  448.         ID3D12DescriptorHeap* ppHeaps[] = { m_cbvHeap.Get() };
  449.         m_commandList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps);
  450.  
  451.         // Bind the current frame's constant buffer to the pipeline.
  452.         CD3DX12_GPU_DESCRIPTOR_HANDLE gpuHandle(m_cbvHeap->GetGPUDescriptorHandleForHeapStart(), m_deviceResources->GetCurrentFrameIndex(), m_cbvDescriptorSize);
  453.         m_commandList->SetGraphicsRootDescriptorTable(0, gpuHandle);
  454.  
  455.         // Set the viewport and scissor rectangle.
  456.         D3D12_VIEWPORT viewport = m_deviceResources->GetScreenViewport();
  457.         m_commandList->RSSetViewports(1, &viewport);
  458.         m_commandList->RSSetScissorRects(1, &m_scissorRect);
  459.  
  460.         // Indicate this resource will be in use as a render target.
  461.         CD3DX12_RESOURCE_BARRIER renderTargetResourceBarrier =
  462.             CD3DX12_RESOURCE_BARRIER::Transition(m_deviceResources->GetRenderTarget(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
  463.         m_commandList->ResourceBarrier(1, &renderTargetResourceBarrier);
  464.  
  465.         // Record drawing commands.
  466.         m_commandList->ClearRenderTargetView(m_deviceResources->GetRenderTargetView(), DirectX::Colors::CornflowerBlue, 0, nullptr);
  467.         D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView = m_deviceResources->GetRenderTargetView();
  468.         m_commandList->OMSetRenderTargets(1, &renderTargetView, false, nullptr);
  469.  
  470.         m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  471.         m_commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
  472.         m_commandList->IASetIndexBuffer(&m_indexBufferView);
  473.         m_commandList->DrawIndexedInstanced(36, 1, 0, 0, 0);
  474.  
  475.         // Indicate that the render target will now be used to present when the command list is done executing.
  476.         CD3DX12_RESOURCE_BARRIER presentResourceBarrier =
  477.             CD3DX12_RESOURCE_BARRIER::Transition(m_deviceResources->GetRenderTarget(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
  478.         m_commandList->ResourceBarrier(1, &presentResourceBarrier);
  479.     }
  480.     PIXEndEvent(m_commandList.Get());
  481.  
  482.     DX::ThrowIfFailed(m_commandList->Close());
  483.  
  484.     // Execute the command list.
  485.     ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
  486.     m_deviceResources->GetCommandQueue()->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
  487.  
  488.     return true;
  489. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement