|
|
@@ -18,6 +18,13 @@ bool D3DBox::Initialize()
|
|
|
if (!D3DApp::Initialize())
|
|
|
return false;
|
|
|
|
|
|
+ BuildDescriptorHeaps();
|
|
|
+ BuildConstantBuffers();
|
|
|
+ BuildRootSignature();
|
|
|
+ BuildShaderAndInputLayout();
|
|
|
+ BuildBoxGeometry();
|
|
|
+ BuildPSO();
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
@@ -35,6 +42,156 @@ void D3DBox::Draw(const GameTimer& gt)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
+void D3DBox::OnMouseDown(WPARAM btnState, int x, int y)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+void D3DBox::OnMouseUp(WPARAM btnState, int x, int y)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+void D3DBox::OnMouseMove(WPARAM btnStae, int x, int y)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+void D3DBox::BuildDescriptorHeaps()
|
|
|
+{
|
|
|
+ D3D12_DESCRIPTOR_HEAP_DESC cbvHeapDesc;
|
|
|
+ cbvHeapDesc.NodeMask = 0;
|
|
|
+ cbvHeapDesc.NumDescriptors = 1;
|
|
|
+ cbvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
|
|
+ cbvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
|
|
+ md3dDevice->CreateDescriptorHeap(&cbvHeapDesc, IID_PPV_ARGS(&mCbvHeap));
|
|
|
+}
|
|
|
+
|
|
|
+void D3DBox::BuildConstantBuffers()
|
|
|
+{
|
|
|
+ mObjectCB = std::make_unique<UploadBuffer<ObjectConstants>>(md3dDevice.Get(), 1, true);
|
|
|
+
|
|
|
+
|
|
|
+ UINT objCBByteSize = d3dUtil::CalcConstantBufferByteSize(sizeof(ObjectConstants)); // 要求大小是硬件最低配置 256b 的整数倍
|
|
|
+
|
|
|
+ D3D12_GPU_VIRTUAL_ADDRESS cbAddress = mObjectCB->Resource()->GetGPUVirtualAddress();
|
|
|
+
|
|
|
+ int boxCBBufferIndex = 0;
|
|
|
+ cbAddress += boxCBBufferIndex * objCBByteSize; // 计算地址偏移, 如果缓冲区中存储多个 ObjectConstants 将指定数据创建描述符
|
|
|
+
|
|
|
+ D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc;
|
|
|
+ cbvDesc.BufferLocation = cbAddress;
|
|
|
+ cbvDesc.SizeInBytes = objCBByteSize;
|
|
|
+
|
|
|
+ md3dDevice->CreateConstantBufferView(&cbvDesc, mCbvHeap->GetCPUDescriptorHandleForHeapStart()); // 创建CBV描述符
|
|
|
+ // 如果 cbvheap 绑定过其他 cbv 可能需要通过 offset 计算偏移
|
|
|
+}
|
|
|
+
|
|
|
+void D3DBox::BuildRootSignature()
|
|
|
+{
|
|
|
+ CD3DX12_ROOT_PARAMETER slotRootParameter[1];
|
|
|
+
|
|
|
+ CD3DX12_DESCRIPTOR_RANGE cbvTable;
|
|
|
+ cbvTable.Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); // 绑定一个 CBV 到第 0 个寄存器中
|
|
|
+ slotRootParameter[0].InitAsDescriptorTable(1, &cbvTable);
|
|
|
+
|
|
|
+ // 创建一个带有 一个 常量表 的根标签
|
|
|
+ CD3DX12_ROOT_SIGNATURE_DESC rootSigDesc(1, slotRootParameter, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
|
|
|
+
|
|
|
+ ComPtr<ID3DBlob> serializedRootSig = nullptr;
|
|
|
+ ComPtr<ID3DBlob> errorBlob = nullptr;
|
|
|
+
|
|
|
+ HRESULT hr = D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, serializedRootSig.GetAddressOf(), errorBlob.GetAddressOf());
|
|
|
+
|
|
|
+ if (errorBlob != nullptr)
|
|
|
+ {
|
|
|
+ ::OutputDebugStringA((char*)errorBlob->GetBufferPointer());
|
|
|
+ }
|
|
|
+ ThrowIfFailed(hr);
|
|
|
+
|
|
|
+ md3dDevice->CreateRootSignature(0, serializedRootSig->GetBufferPointer(), serializedRootSig->GetBufferSize(), IID_PPV_ARGS(&mRootSignature));
|
|
|
+}
|
|
|
+
|
|
|
+void D3DBox::BuildShaderAndInputLayout()
|
|
|
+{
|
|
|
+ mVSByteCode = d3dUtil::CompileShader(L"res/color.hlsl", nullptr, "VS", "vs_5_0");
|
|
|
+ mPSByteCode = d3dUtil::CompileShader(L"res/color.hlsl", nullptr, "PS", "ps_5_0");
|
|
|
+
|
|
|
+ mInputLayout =
|
|
|
+ {
|
|
|
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
|
|
+ { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+void D3DBox::BuildPSO()
|
|
|
+{
|
|
|
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
|
|
|
+
|
|
|
+ ZeroMemory(&psoDesc, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
|
|
|
+ psoDesc.InputLayout = { mInputLayout.data(), (UINT)mInputLayout.size() };
|
|
|
+ psoDesc.pRootSignature = mRootSignature.Get();
|
|
|
+ psoDesc.VS = { mVSByteCode->GetBufferPointer(), mVSByteCode->GetBufferSize() };
|
|
|
+ psoDesc.PS = { mPSByteCode->GetBufferPointer(), mPSByteCode->GetBufferSize() };
|
|
|
+ psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
|
|
|
+ psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
|
|
|
+ psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
|
|
|
+ psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
|
|
+ psoDesc.SampleMask = UINT_MAX;
|
|
|
+ psoDesc.NumRenderTargets = 1;
|
|
|
+ psoDesc.RTVFormats[0] = mBackBufferFormat;
|
|
|
+ psoDesc.SampleDesc.Count = m4xMsaaState ? 4 : 1;
|
|
|
+ psoDesc.SampleDesc.Quality = m4xMsaaState ? (m4xMsaaQuality - 1) : 0;
|
|
|
+ psoDesc.DSVFormat = mDepthStencilFormat;
|
|
|
+
|
|
|
+ md3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPSO));
|
|
|
+}
|
|
|
+
|
|
|
+void D3DBox::BuildBoxGeometry()
|
|
|
+{
|
|
|
+ std::array<Vertex, 8> vertices =
|
|
|
+ {
|
|
|
+ Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::White) }),
|
|
|
+ Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
|
|
|
+ Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
|
|
|
+ Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
|
|
|
+ Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Blue) }),
|
|
|
+ Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
|
|
|
+ Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
|
|
|
+ Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Magenta) })
|
|
|
+ };
|
|
|
+
|
|
|
+ std::array<std::uint16_t, 36> indices =
|
|
|
+ {
|
|
|
+ // front face
|
|
|
+ 0, 1, 2,
|
|
|
+ 0, 2, 3,
|
|
|
+
|
|
|
+ // back face
|
|
|
+ 4, 6, 5,
|
|
|
+ 4, 7, 6,
|
|
|
+
|
|
|
+ // left face
|
|
|
+ 4, 5, 1,
|
|
|
+ 4, 1, 0,
|
|
|
+
|
|
|
+ // right face
|
|
|
+ 3, 2, 6,
|
|
|
+ 3, 6, 7,
|
|
|
+
|
|
|
+ // top face
|
|
|
+ 1, 5, 6,
|
|
|
+ 1, 6, 2,
|
|
|
+
|
|
|
+ // bottom face
|
|
|
+ 4, 0, 3,
|
|
|
+ 4, 3, 7
|
|
|
+ };
|
|
|
+
|
|
|
+ const UINT vbByteSize = (UINT)vertices.size() * sizeof(Vertex);
|
|
|
+ const UINT ibByteSize = (UINT)indices.size() * sizeof(std::uint16_t);
|
|
|
+
|
|
|
+ mBoxGeo = std::make_unique<MeshGeometry>();
|
|
|
+ mBoxGeo->Name = "boxGeo";
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
|
|
|
_In_opt_ HINSTANCE hPrevInstance,
|