| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- #include "ShapeApp.h"
- #include "GeometryGenerator.h"
- const std::string PSKey = "PS";
- const std::string VSKey = "VS";
- ShapeApp::ShapeApp(HINSTANCE hInstance) : D3DApp(hInstance)
- {
- }
- ShapeApp::~ShapeApp()
- {
- }
- bool ShapeApp::Initialize()
- {
- if (!D3DApp::Initialize()) {
- return false;
- }
- // 重置命令列表
- ThrowIfFailed(mCommandList->Reset(mCommandAllocator.Get(), nullptr));
- BuildRootSignature();
- BuildShaderAndInputLayout();
- BuildShapeGeometry();
- BuildRenderItems();
- BuildFrameResource();
- BuildDescriptorHeaps();
- BuildConstantBuffers();
- BuildPSO();
- // 执行初始化时的命令
- ThrowIfFailed(mCommandList->Close());
- ID3D12CommandList* cmdsLists[] = { mCommandList.Get() };
- mCommandQueue->ExecuteCommandLists(_countof(cmdsLists), cmdsLists);
- // 等待初始化命令完成
- FlushCommandQueue();
- return true;
- }
- void ShapeApp::OnResize()
- {
- D3DApp::OnResize();
- // 窗口大小更新时 更新视图矩阵
- XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f * MathHelper::Pi, AspectRatio(), 1.0f, 1000.0f);
- XMStoreFloat4x4(&mProj, P);
- }
- void ShapeApp::Update(const GameTimer& gt)
- {
- UpdateCamera(); // 更 View 矩阵
- // 确定当前使用的帧资源索引序号和帧资源
- mCurrFrameResourceIndex = (mCurrFrameResourceIndex + 1) % gNumFrameResources;
- mCurrFrameResource = mFrameResources[mCurrFrameResourceIndex].get();
- // 如果当前帧资源并没有被 GPU 使用,则强制等待
- if (mCurrFrameResource->Fence != 0 && mFence->GetCompletedValue() < mCurrFrameResource->Fence)
- {
- HANDLE eventHandle = CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS);
- ThrowIfFailed(mFence->SetEventOnCompletion(mCurrFrameResource->Fence, eventHandle));
- WaitForSingleObject(eventHandle, INFINITE);
- CloseHandle(eventHandle);
- }
- UpdateObjectCBs();
- UpdateMainPassCB(gt);
- }
- void ShapeApp::Draw(const GameTimer& gt)
- {
- auto cmdListAlloc = mCurrFrameResource->CmdListAlloc;
- cmdListAlloc->Reset();
- if (mIsWireframe)
- {
- ThrowIfFailed(mCommandList->Reset(cmdListAlloc.Get(), mPSOs["opaque_wireframe"].Get()));
- }
- else
- {
- ThrowIfFailed(mCommandList->Reset(cmdListAlloc.Get(), mPSOs["opaque"].Get()));
- }
- mCommandList->RSSetViewports(1, &mScreenViewport);
- mCommandList->RSSetScissorRects(1, &mScissorRect);
- mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(CurrentBackBuffer(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
- mCommandList->ClearRenderTargetView(CurrentBackBufferView(), Colors::LightSteelBlue, 0, nullptr);
- mCommandList->ClearDepthStencilView(DepthStencilView(), D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, 0, nullptr);
- mCommandList->OMSetRenderTargets(1, &CurrentBackBufferView(), true, &DepthStencilView());
- ID3D12DescriptorHeap* descHeaps[] = { mCbvHeap.Get() };
- mCommandList->SetDescriptorHeaps(_countof(descHeaps), descHeaps);
- mCommandList->SetGraphicsRootSignature(mRootSignature.Get());
- int passCbvIndex = mPassCbvOffset + mCurrFrameResourceIndex;
- auto passCbvHandle = CD3DX12_GPU_DESCRIPTOR_HANDLE(mCbvHeap->GetGPUDescriptorHandleForHeapStart());
- passCbvHandle.Offset(passCbvIndex, mCbvSrvUavDescriptorSize);
- mCommandList->SetGraphicsRootDescriptorTable(1, passCbvHandle);
- DrawRenderItems(mCommandList.Get(), mOpaqueRitems);
- mCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(CurrentBackBuffer(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
-
- mCommandList->Close();
- ID3D12CommandList* cmdList[] = { mCommandList.Get() };
- mCommandQueue->ExecuteCommandLists(_countof(cmdList), cmdList);
- ThrowIfFailed(mSwapChain->Present(0, 0));
- mCurrentBackBuffer = (mCurrentBackBuffer + 1) % SwapChainBufferCount;
- mCurrFrameResource->Fence = ++mCurrentFence;
- mCommandQueue->Signal(mFence.Get(), mCurrentFence);
- }
- void ShapeApp::OnMouseDown(WPARAM btnState, int x, int y)
- {
- mLastMousePos.x = x;
- mLastMousePos.y = y;
- SetCapture(mhMainWnd);
- }
- void ShapeApp::OnMouseUp(WPARAM btnState, int x, int y)
- {
- ReleaseCapture();
- }
- void ShapeApp::OnMouseMove(WPARAM btnState, int x, int y)
- {
- if ((btnState & MK_LBUTTON) != 0)
- {
- float dx = XMConvertToRadians(0.25f * static_cast<float>(x - mLastMousePos.x));
- float dy = XMConvertToRadians(0.25f * static_cast<float>(y - mLastMousePos.y));
- mTheta += dx;
- mPhi += dy;
- mPhi = MathHelper::Clamp(mPhi, 0.1f, MathHelper::Pi - 0.1f);
- }
- else if ((btnState & MK_RBUTTON) != 0)
- {
- float dx = 0.005f * static_cast<float>(x - mLastMousePos.x);
- float dy = 0.005f * static_cast<float>(y - mLastMousePos.y);
- mRadius += dx - dy;
- mRadius = MathHelper::Clamp(mRadius, 3.0f, 15.0f);
- }
- mLastMousePos.x = x;
- mLastMousePos.y = y;
- }
- void ShapeApp::BuildDescriptorHeaps()
- {
- UINT renderNum = mOpaqueRitems.size();
- // 每个渲染项一个 CBV,再加一个 PrePass CBV 用于给每个渲染项共享的 CBV
- // 由于有 gNumFrameResources 帧资源,所以是 (renderNum + 1) * gNumFrameResources
- UINT descNum = (renderNum + 1) * gNumFrameResources;
- // 计算 PrePass CBV 在堆描述符中的偏移
- // 以 gNumFrameResources 为 3,renderNum 为 4 为例
- // 前面 4 * 3 表示 3 个帧资源 每个帧资源的 4 个渲染项的 CBV,最后 3 个 表示每个帧资源的 PrePass CBV
- // 所以 PrePass CBV 的偏移地址就是 renderNum * gNumFrameResources
- mPassCbvOffset = renderNum * gNumFrameResources;
- D3D12_DESCRIPTOR_HEAP_DESC desc;
- desc.NumDescriptors = descNum;
- desc.NodeMask = 0;
- desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
- desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
- md3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&mCbvHeap));
- }
- void ShapeApp::BuildConstantBuffers()
- {
- UINT objCBByteSize = d3dUtil::CalcConstantBufferByteSize(sizeof(ObjectConstants));
- UINT objCount = (UINT)mOpaqueRitems.size();
- // 创建 Render Item 的 CBV
- for (int frameIndex = 0; frameIndex < gNumFrameResources; ++frameIndex) {
- auto objectCB = mFrameResources[frameIndex]->ObjectCB->Resource();
- for (int itemIndex = 0; itemIndex < objCount; ++itemIndex) {
- D3D12_GPU_VIRTUAL_ADDRESS cbAddress = objectCB->GetGPUVirtualAddress();
- cbAddress += itemIndex * objCBByteSize;
- int heapIndex = frameIndex * objCount + itemIndex;
- auto handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(mCbvHeap->GetCPUDescriptorHandleForHeapStart());
- handle.Offset(heapIndex, mCbvSrvUavDescriptorSize);
- D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc;
- cbvDesc.BufferLocation = cbAddress;
- cbvDesc.SizeInBytes = objCBByteSize;
- md3dDevice->CreateConstantBufferView(&cbvDesc, handle);
- }
- }
- // 创建 pre pass CBV
- for (int frameIndex = 0; frameIndex < gNumFrameResources; ++frameIndex) {
- auto passCB = mFrameResources[frameIndex]->PassCB->Resource();
- D3D12_GPU_VIRTUAL_ADDRESS cbAddress = passCB->GetGPUVirtualAddress();
- int heapIndex = mPassCbvOffset + frameIndex;
- auto handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(mCbvHeap->GetCPUDescriptorHandleForHeapStart());
- handle.Offset(heapIndex, mCbvSrvUavDescriptorSize);
- D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc;
- cbvDesc.BufferLocation = cbAddress;
- cbvDesc.SizeInBytes = objCBByteSize;
- md3dDevice->CreateConstantBufferView(&cbvDesc, handle);
- }
- }
- void ShapeApp::BuildRootSignature()
- {
- CD3DX12_DESCRIPTOR_RANGE cbvTable0;
- cbvTable0.Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
- CD3DX12_DESCRIPTOR_RANGE cbvTable1;
- cbvTable1.Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 1);
- CD3DX12_ROOT_PARAMETER rootParameters[2];
- rootParameters[0].InitAsDescriptorTable(1, &cbvTable0);
- rootParameters[1].InitAsDescriptorTable(1, &cbvTable1);
- CD3DX12_ROOT_SIGNATURE_DESC rootSigDesc(2, rootParameters, 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);
- ThrowIfFailed(md3dDevice->CreateRootSignature(0, serializedRootSig->GetBufferPointer(), serializedRootSig->GetBufferSize(), IID_PPV_ARGS(mRootSignature.GetAddressOf())));
- }
- void ShapeApp::BuildShaderAndInputLayout()
- {
- mShaders[VSKey] = d3dUtil::CompileShader(L"res/shape.hlsl", nullptr, VSKey, "vs_5_1");
- mShaders[PSKey] = d3dUtil::CompileShader(L"res/shape.hlsl", nullptr, PSKey, "ps_5_1");
- 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 ShapeApp::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 = { reinterpret_cast<BYTE*>(mShaders[VSKey]->GetBufferPointer()), mShaders[VSKey]->GetBufferSize() };
- psoDesc.PS = { reinterpret_cast<BYTE*>(mShaders[PSKey]->GetBufferPointer()), mShaders[PSKey]->GetBufferSize() };
- psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
- psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
- psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
- psoDesc.SampleMask = UINT_MAX;
- psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
- psoDesc.NumRenderTargets = 1;
- psoDesc.RTVFormats[0] = mBackBufferFormat;
- psoDesc.SampleDesc.Count = m4xMsaaState ? 4 : 1;
- psoDesc.SampleDesc.Quality = m4xMsaaState ? m4xMsaaQuality - 1 : 0;
- psoDesc.DSVFormat = mDepthStencilFormat;
- psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
- md3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPSOs["opaque"]));
- D3D12_GRAPHICS_PIPELINE_STATE_DESC opaqueWireframePsoDesc = psoDesc;
- opaqueWireframePsoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_WIREFRAME; // 使用 WIREFRAME 线框模式
- md3dDevice->CreateGraphicsPipelineState(&opaqueWireframePsoDesc, IID_PPV_ARGS(&mPSOs["opaque_wireframe"]));
- }
- void ShapeApp::BuildRenderItems()
- {
- auto boxRitem = std::make_unique<RenderItem>();
- XMStoreFloat4x4(&boxRitem->World, XMMatrixScaling(2.0f, 2.0f, 2.0f) * XMMatrixTranslation(0.0f, 0.5f, 0.0f));
- boxRitem->ObjCBIndex = 0;
- boxRitem->Geo = mGeometries["shapeGeo"].get();
- boxRitem->PrimitiveType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
- boxRitem->IndexCount = boxRitem->Geo->DrawArgs["box"].IndexCount;
- boxRitem->StartIndexLocation = boxRitem->Geo->DrawArgs["box"].StartIndexLocation;
- boxRitem->BaseVertexLocation = boxRitem->Geo->DrawArgs["box"].BaseVertexLocation;
- mAllRitems.push_back(std::move(boxRitem));
- auto gridRitem = std::make_unique<RenderItem>();
- gridRitem->World = MathHelper::Identity4x4();
- gridRitem->ObjCBIndex = 1;
- gridRitem->Geo = mGeometries["shapeGeo"].get();
- gridRitem->PrimitiveType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
- gridRitem->IndexCount = gridRitem->Geo->DrawArgs["grid"].IndexCount;
- gridRitem->StartIndexLocation = gridRitem->Geo->DrawArgs["grid"].StartIndexLocation;
- gridRitem->BaseVertexLocation = gridRitem->Geo->DrawArgs["grid"].BaseVertexLocation;
- mAllRitems.push_back(std::move(gridRitem));
- UINT objCBIndex = 2;
- for (int i = 0; i < 5; ++i)
- {
- auto leftCylRitem = std::make_unique<RenderItem>();
- auto rightCylRitem = std::make_unique<RenderItem>();
- auto leftSphereRitem = std::make_unique<RenderItem>();
- auto rightSphereRitem = std::make_unique<RenderItem>();
- XMMATRIX leftCylWorld = XMMatrixTranslation(-5.0f, 1.5f, -10.0f + i * 5.0f);
- XMMATRIX rightCylWorld = XMMatrixTranslation(+5.0f, 1.5f, -10.0f + i * 5.0f);
- XMMATRIX leftSphereWorld = XMMatrixTranslation(-5.0f, 3.5f, -10.0f + i * 5.0f);
- XMMATRIX rightSphereWorld = XMMatrixTranslation(+5.0f, 3.5f, -10.0f + i * 5.0f);
- XMStoreFloat4x4(&leftCylRitem->World, rightCylWorld);
- leftCylRitem->ObjCBIndex = objCBIndex++;
- leftCylRitem->Geo = mGeometries["shapeGeo"].get();
- leftCylRitem->PrimitiveType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
- leftCylRitem->IndexCount = leftCylRitem->Geo->DrawArgs["cylinder"].IndexCount;
- leftCylRitem->StartIndexLocation = leftCylRitem->Geo->DrawArgs["cylinder"].StartIndexLocation;
- leftCylRitem->BaseVertexLocation = leftCylRitem->Geo->DrawArgs["cylinder"].BaseVertexLocation;
- XMStoreFloat4x4(&rightCylRitem->World, leftCylWorld);
- rightCylRitem->ObjCBIndex = objCBIndex++;
- rightCylRitem->Geo = mGeometries["shapeGeo"].get();
- rightCylRitem->PrimitiveType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
- rightCylRitem->IndexCount = rightCylRitem->Geo->DrawArgs["cylinder"].IndexCount;
- rightCylRitem->StartIndexLocation = rightCylRitem->Geo->DrawArgs["cylinder"].StartIndexLocation;
- rightCylRitem->BaseVertexLocation = rightCylRitem->Geo->DrawArgs["cylinder"].BaseVertexLocation;
- XMStoreFloat4x4(&leftSphereRitem->World, leftSphereWorld);
- leftSphereRitem->ObjCBIndex = objCBIndex++;
- leftSphereRitem->Geo = mGeometries["shapeGeo"].get();
- leftSphereRitem->PrimitiveType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
- leftSphereRitem->IndexCount = leftSphereRitem->Geo->DrawArgs["sphere"].IndexCount;
- leftSphereRitem->StartIndexLocation = leftSphereRitem->Geo->DrawArgs["sphere"].StartIndexLocation;
- leftSphereRitem->BaseVertexLocation = leftSphereRitem->Geo->DrawArgs["sphere"].BaseVertexLocation;
- XMStoreFloat4x4(&rightSphereRitem->World, rightSphereWorld);
- rightSphereRitem->ObjCBIndex = objCBIndex++;
- rightSphereRitem->Geo = mGeometries["shapeGeo"].get();
- rightSphereRitem->PrimitiveType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
- rightSphereRitem->IndexCount = rightSphereRitem->Geo->DrawArgs["sphere"].IndexCount;
- rightSphereRitem->StartIndexLocation = rightSphereRitem->Geo->DrawArgs["sphere"].StartIndexLocation;
- rightSphereRitem->BaseVertexLocation = rightSphereRitem->Geo->DrawArgs["sphere"].BaseVertexLocation;
- mAllRitems.push_back(std::move(leftCylRitem));
- mAllRitems.push_back(std::move(rightCylRitem));
- mAllRitems.push_back(std::move(leftSphereRitem));
- mAllRitems.push_back(std::move(rightSphereRitem));
- }
- // All the render items are opaque.
- for (auto& e : mAllRitems)
- mOpaqueRitems.push_back(e.get());
- }
- void ShapeApp::BuildShapeGeometry()
- {
- GeometryGenerator geoGen;
- GeometryGenerator::MeshData box = geoGen.CreateBox(1.5f, 0.5f, 1.5f, 3);
- GeometryGenerator::MeshData grid = geoGen.CreateGrid(20.0f, 30.0f, 60, 40);
- GeometryGenerator::MeshData sphere = geoGen.CreateSphere(0.5f, 20, 20);
- GeometryGenerator::MeshData cylinder = geoGen.CreateCylinder(0.5f, 0.3f, 3.0f, 20, 20);
- // 定义各个模型顶点缓冲区的偏移
- UINT boxVertexOffset = 0;
- UINT gridVertexOffset = (UINT)box.Vertices.size();
- UINT sphereVertexOffset = gridVertexOffset + (UINT)grid.Vertices.size();
- UINT cylinderVertexOffset = sphereVertexOffset + (UINT)sphere.Vertices.size();
- // 定义各个模型顶点索引缓冲区的偏移
- UINT boxIndexOffset = 0;
- UINT gridIndexOffset = (UINT)box.Indices32.size();
- UINT sphereIndexOffset = gridIndexOffset + (UINT)grid.Indices32.size();
- UINT cylinderIndexOffset = sphereIndexOffset + (UINT)sphere.Indices32.size();
- // 构建子模型
- SubmeshGeometry boxSubmesh;
- boxSubmesh.IndexCount = (UINT)box.Indices32.size();
- boxSubmesh.StartIndexLocation = boxIndexOffset;
- boxSubmesh.BaseVertexLocation = boxVertexOffset;
- SubmeshGeometry gridSubmesh;
- gridSubmesh.IndexCount = (UINT)grid.Indices32.size();
- gridSubmesh.StartIndexLocation = gridIndexOffset;
- gridSubmesh.BaseVertexLocation = gridVertexOffset;
- SubmeshGeometry sphereSubmesh;
- sphereSubmesh.IndexCount = (UINT)sphere.Indices32.size();
- sphereSubmesh.StartIndexLocation = sphereIndexOffset;
- sphereSubmesh.BaseVertexLocation = sphereVertexOffset;
- SubmeshGeometry cylinderSubmesh;
- cylinderSubmesh.IndexCount = (UINT)cylinder.Indices32.size();
- cylinderSubmesh.StartIndexLocation = cylinderIndexOffset;
- cylinderSubmesh.BaseVertexLocation = cylinderVertexOffset;
- auto totalVertexCount = box.Vertices.size() + grid.Vertices.size() + sphere.Vertices.size() + cylinder.Vertices.size();
- std::vector<Vertex> vertices(totalVertexCount);
- UINT k = 0;
- for (size_t i = 0; i < box.Vertices.size(); ++i, ++k)
- {
- vertices[k].Pos = box.Vertices[i].Position;
- vertices[k].Color = XMFLOAT4(DirectX::Colors::DarkGreen);
- }
- for (size_t i = 0; i < grid.Vertices.size(); ++i, ++k)
- {
- vertices[k].Pos = grid.Vertices[i].Position;
- vertices[k].Color = XMFLOAT4(DirectX::Colors::ForestGreen);
- }
- for (size_t i = 0; i < sphere.Vertices.size(); ++i, ++k)
- {
- vertices[k].Pos = sphere.Vertices[i].Position;
- vertices[k].Color = XMFLOAT4(DirectX::Colors::Crimson);
- }
- for (size_t i = 0; i < cylinder.Vertices.size(); ++i, ++k)
- {
- vertices[k].Pos = cylinder.Vertices[i].Position;
- vertices[k].Color = XMFLOAT4(DirectX::Colors::SteelBlue);
- }
- std::vector<std::uint16_t> indices;
- indices.insert(indices.end(), std::begin(box.GetIndices16()), std::end(box.GetIndices16()));
- indices.insert(indices.end(), std::begin(grid.GetIndices16()), std::end(grid.GetIndices16()));
- indices.insert(indices.end(), std::begin(sphere.GetIndices16()), std::end(sphere.GetIndices16()));
- indices.insert(indices.end(), std::begin(cylinder.GetIndices16()), std::end(cylinder.GetIndices16()));
- const UINT vbByteSize = (UINT)vertices.size() * sizeof(Vertex);
- const UINT ibByteSize = (UINT)indices.size() * sizeof(std::uint16_t);
- auto geo = std::make_unique<MeshGeometry>();
- geo->Name = "shapeGeo";
- ThrowIfFailed(D3DCreateBlob(vbByteSize, &geo->VertexBufferCPU));
- CopyMemory(geo->VertexBufferCPU->GetBufferPointer(), vertices.data(), vbByteSize);
- ThrowIfFailed(D3DCreateBlob(ibByteSize, &geo->IndexBufferCPU));
- CopyMemory(geo->IndexBufferCPU->GetBufferPointer(), indices.data(), ibByteSize);
- geo->VertexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(), mCommandList.Get(), vertices.data(), vbByteSize, geo->VertexBufferUploader);
- geo->IndexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(), mCommandList.Get(), indices.data(), ibByteSize, geo->IndexBufferUploader);
- geo->VertexByteStride = sizeof(Vertex);
- geo->VertexBufferByteSize = vbByteSize;
- geo->IndexFormat = DXGI_FORMAT_R16_UINT;
- geo->IndexBufferByteSize = ibByteSize;
- geo->DrawArgs["box"] = boxSubmesh;
- geo->DrawArgs["grid"] = gridSubmesh;
- geo->DrawArgs["sphere"] = sphereSubmesh;
- geo->DrawArgs["cylinder"] = cylinderSubmesh;
- mGeometries[geo->Name] = std::move(geo);
- }
- void ShapeApp::BuildFrameResource()
- {
- for (int i = 0; i < gNumFrameResources; ++i) {
- mFrameResources.push_back(std::make_unique<FrameResource>(md3dDevice.Get(), 1, (UINT)mAllRitems.size()));
- }
- }
- void ShapeApp::UpdateCamera()
- {
- mEyePos.x = mRadius * sinf(mPhi) * cosf(mTheta);
- mEyePos.z = mRadius * sinf(mPhi) * sinf(mTheta);
- mEyePos.y = mRadius * cosf(mPhi);
- // Build the view matrix.
- XMVECTOR pos = XMVectorSet(mEyePos.x, mEyePos.y, mEyePos.z, 1.0f);
- XMVECTOR target = XMVectorZero();
- XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
- XMMATRIX view = XMMatrixLookAtLH(pos, target, up);
- XMStoreFloat4x4(&mView, view);
- }
- void ShapeApp::UpdateObjectCBs()
- {
- auto currObjectCB = mCurrFrameResource->ObjectCB.get();
- for (auto& e : mAllRitems)
- {
- if (e->NumFramesDirty > 0)
- {
- XMMATRIX world = XMLoadFloat4x4(&e->World);
- ObjectConstants objConstants;
- XMStoreFloat4x4(&objConstants.World, XMMatrixTranspose(world));
- currObjectCB->CopyData(e->ObjCBIndex, objConstants);
- e->NumFramesDirty--;
- }
- }
- }
- void ShapeApp::UpdateMainPassCB(const GameTimer& gt)
- {
- XMMATRIX view = XMLoadFloat4x4(&mView);
- XMMATRIX proj = XMLoadFloat4x4(&mProj);
- XMMATRIX viewProj = XMMatrixMultiply(view, proj);
- XMMATRIX invView = XMMatrixInverse(&XMMatrixDeterminant(view), view);
- XMMATRIX invProj = XMMatrixInverse(&XMMatrixDeterminant(proj), proj);
- XMMATRIX invViewProj = XMMatrixInverse(&XMMatrixDeterminant(viewProj), viewProj);
- XMStoreFloat4x4(&mMainPassCB.View, XMMatrixTranspose(view));
- XMStoreFloat4x4(&mMainPassCB.InvView, XMMatrixTranspose(invView));
- XMStoreFloat4x4(&mMainPassCB.Proj, XMMatrixTranspose(proj));
- XMStoreFloat4x4(&mMainPassCB.InvProj, XMMatrixTranspose(invProj));
- XMStoreFloat4x4(&mMainPassCB.ViewProj, XMMatrixTranspose(viewProj));
- XMStoreFloat4x4(&mMainPassCB.InvViewProj, XMMatrixTranspose(invViewProj));
- mMainPassCB.EyePosW = mEyePos;
- mMainPassCB.RenderTargetSize = XMFLOAT2((float)mClientWidth, (float)mClientHeight);
- mMainPassCB.InvRenderTargetSize = XMFLOAT2(1.0f / mClientWidth, 1.0f / mClientHeight);
- mMainPassCB.NearZ = 1.0f;
- mMainPassCB.FarZ = 1000.0f;
- mMainPassCB.TotalTime = gt.TotalTime();
- mMainPassCB.DeltaTime = gt.DeltaTime();
- auto currPassCB = mCurrFrameResource->PassCB.get();
- currPassCB->CopyData(0, mMainPassCB);
- }
- void ShapeApp::DrawRenderItems(ID3D12GraphicsCommandList* cmdList, const std::vector<RenderItem*>& ritems)
- {
- UINT objCBByteSize = d3dUtil::CalcConstantBufferByteSize(sizeof(ObjectConstants));
- auto objectCB = mCurrFrameResource->ObjectCB->Resource();
- for (size_t index = 0; index < ritems.size(); ++index) {
- const auto& ri = ritems[index];
- cmdList->IASetVertexBuffers(0, 1, &ri->Geo->VertexBufferView());
- cmdList->IASetIndexBuffer(&ri->Geo->IndexBufferView());
- cmdList->IASetPrimitiveTopology(ri->PrimitiveType);
- UINT cbvIndex = mCurrFrameResourceIndex * (UINT)mOpaqueRitems.size() + ri->ObjCBIndex;
- auto cbvHandle = CD3DX12_GPU_DESCRIPTOR_HANDLE(mCbvHeap->GetGPUDescriptorHandleForHeapStart());
- cbvHandle.Offset(cbvIndex, mCbvSrvUavDescriptorSize);
- cmdList->SetGraphicsRootDescriptorTable(0, cbvHandle);
- cmdList->DrawIndexedInstanced(ri->IndexCount, 1, ri->StartIndexLocation, ri->BaseVertexLocation, 0);
- }
- }
|