stuff-from-scratch/src/graphics/directx/DirectXMesh.cpp
2023-01-12 09:18:16 +00:00

141 lines
No EOL
4.9 KiB
C++

#include "DirectXMesh.h"
#include "SceneModel.h"
#include "DrawingContext.h"
#include "DrawingSurface.h"
#include "TriMesh.h"
#include "TriFace.h"
#include "FileLogger.h"
#include <directx/d3dx12.h>
DirectXMesh::DirectXMesh(SceneModel* model)
: mModel(model)
{
}
void DirectXMesh::update(DrawingContext* context, ID3D12Device* device)
{
mVertexBuffer.clear();
mIndexBuffer.clear();
const auto width = float(context->getSurface()->getWidth());
const auto height = float(context->getSurface()->getHeight());
auto model_color = mModel->getFillColor().getAsVectorDouble();
std::vector<float> color = { float(model_color[0]), float(model_color[1]), float(model_color[2]), float(model_color[3]) };
auto transform = mModel->getTransform();
for (const auto& face : dynamic_cast<TriMesh*>(mModel->getMesh())->getFaces())
{
for (const auto& loc : face->getNodeLocations(AbstractFace::Orientation::CW))
{
auto x = loc.getX() * transform.getScaleX() + transform.getLocation().getX();
auto y = loc.getY() * transform.getScaleY() + transform.getLocation().getY();
x = 2 * x - 1;
y = 2 * y - 1;
Vertex vert;
vert.position = DirectX::XMFLOAT3(static_cast<float>(x), static_cast<float>(y), 0.0);
vert.color = DirectX::XMFLOAT4(color[0], color[1], color[2], color[3]);
MLOG_INFO("Adding vert: " << x << " | " << y);
mVertexBuffer.push_back(vert);
}
}
/*
for (const auto& node : mModel->getMesh()->getNodes())
{
auto x = node->getPoint().getX() * transform.getScaleX() + transform.getLocation().getX();
//x = 2 * x / width - 1.0;
auto y = node->getPoint().getY() * transform.getScaleY() + transform.getLocation().getY();
//y = 2 * y / height;
Vertex vert;
vert.position = DirectX::XMFLOAT3(x, y, 0.0);
vert.color = DirectX::XMFLOAT4(color[0], color[1], color[2], color[3]);
MLOG_INFO("Adding vert: " << x << " | " << y);
mVertexBuffer.push_back(vert);
}
*/
//mIndexBuffer = dynamic_cast<TriMesh*>(mModel->getMesh())->getFaceNodeIds();
mIndexBuffer = { 0, 1, 2 };
for (auto id : mIndexBuffer)
{
MLOG_INFO("Adding id: " << id);
}
createD3dVertexBuffer(device);
createD3dIndexBuffer(device);
mVertexBuffer.clear();
mIndexBuffer.clear();
}
void DirectXMesh::createD3dVertexBuffer(ID3D12Device* device)
{
// Note: using upload heaps to transfer static data like vert buffers is not
// recommended. Every time the GPU needs it, the upload heap will be marshalled
// over. Please read up on Default Heap usage. An upload heap is used here for
// code simplicity and because there are very few verts to actually transfer.
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_UPLOAD);
const auto buffer_size = mVertexBuffer.size() * sizeof(Vertex);
auto desc = CD3DX12_RESOURCE_DESC::Buffer(buffer_size);
device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&mD3dVertexBuffer));
UINT8* pDataBegin;
CD3DX12_RANGE readRange(0, 0);
mD3dVertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pDataBegin));
uploadVertexBuffer(pDataBegin);
mD3dVertexBuffer->Unmap(0, nullptr);
mVertexBufferView.BufferLocation = mD3dVertexBuffer->GetGPUVirtualAddress();
mVertexBufferView.StrideInBytes = sizeof(Vertex);
mVertexBufferView.SizeInBytes = static_cast<UINT>(buffer_size);
}
void DirectXMesh::uploadVertexBuffer(unsigned char* pBuffer) const
{
memcpy(pBuffer, mVertexBuffer.data(), mVertexBuffer.size() * sizeof(Vertex));
}
void DirectXMesh::createD3dIndexBuffer(ID3D12Device* device)
{
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_UPLOAD);
const auto buffer_size = mIndexBuffer.size() * sizeof(unsigned);
auto desc = CD3DX12_RESOURCE_DESC::Buffer(buffer_size);
device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&mD3dIndexBuffer));
UINT8* pDataBegin;
CD3DX12_RANGE readRange(0, 0);
mD3dIndexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pDataBegin));
uploadIndexBuffer(pDataBegin);
mD3dIndexBuffer->Unmap(0, nullptr);
mIndexBufferView.BufferLocation = mD3dIndexBuffer->GetGPUVirtualAddress();
mIndexBufferView.SizeInBytes = static_cast<UINT>(buffer_size);
mIndexBufferView.Format = DXGI_FORMAT_R16_UINT;
}
void DirectXMesh::uploadIndexBuffer(unsigned char* pBuffer) const
{
memcpy(pBuffer, mIndexBuffer.data(), mIndexBuffer.size() * sizeof(unsigned));
}
const D3D12_VERTEX_BUFFER_VIEW& DirectXMesh::getVertBufferView() const
{
return mVertexBufferView;
}
const D3D12_INDEX_BUFFER_VIEW& DirectXMesh::getIndexBufferView() const
{
return mIndexBufferView;
}
SceneModel* DirectXMesh::getModel() const
{
return mModel;
}