grafika-latest-working/Geometry.cpp

172 lines
5.2 KiB
C++

//
// Created by Epagris on 2020. 03. 16..
//
#include "Geometry.h"
namespace eg3d {
int ImportAdapters::IAD_Default(XMFLOAT3& vertex)
{
return 0;
}
int ImportAdapters::IAD_SwapYZ_RH(XMFLOAT3& vertex)
{
float y = vertex.y;
vertex.y = vertex.z;
vertex.z = -y;
//vertex.x = vertex.x;
return 0;
}
// -------------------
Geometry::Geometry(ComPtr<ID3D12Device> device) : device(device) {
// topológia beállítása
setTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
Geometry::Geometry(const Geometry &other) : device(other.device) {
setTopology(other.getTopology());
setVertices(other.getVertices());
setIndices(other.getIndices());
}
void Geometry::setVertices(const std::vector<Vertex> &vertices) {
mVertices = vertices;
size_t bufferSize = mVertices.size() * sizeof(Vertex); // buffer mérete
mVertexBuffer.Reset(); // buffer törlése
mVertexBuffer = createBuffer_UH(device, bufferSize); // buffer létrehozása
bufferMapCopy(mVertexBuffer, (void *) mVertices.data(), bufferSize); // buffer feltöltése
// vertex buffer view beállítása
mVertexBufferView.BufferLocation = mVertexBuffer->GetGPUVirtualAddress();
mVertexBufferView.StrideInBytes = sizeof(Vertex);
mVertexBufferView.SizeInBytes = bufferSize;
}
std::vector<Vertex> Geometry::getVertices() const {
return mVertices;
}
void Geometry::setIndices(const std::vector<uint32_t> &indices) {
mIndices = indices;
size_t bufferSize = mIndices.size() * sizeof(uint32_t); // buffer mérete
mIndexBuffer.Reset(); // buffer törlése
mIndexBuffer = createBuffer_UH(device, bufferSize); // buffer létrehozása
bufferMapCopy(mIndexBuffer, (void *) mIndices.data(), bufferSize); // buffer feltöltése
// index buffer view beállítása
mIndexBufferView.Format = /*(sizeof(IT) == 2) ? DXGI_FORMAT_R16_UINT :*/ DXGI_FORMAT_R32_UINT;
mIndexBufferView.BufferLocation = mIndexBuffer->GetGPUVirtualAddress();
mIndexBufferView.SizeInBytes = bufferSize;
}
std::vector<uint32_t> Geometry::getIndices() const {
return mIndices;
}
void Geometry::setTopology(D3D_PRIMITIVE_TOPOLOGY topology) {
mTopology = topology;
}
D3D_PRIMITIVE_TOPOLOGY Geometry::getTopology() const {
return mTopology;
}
void Geometry::setupInputAssembler(ComPtr<ID3D12GraphicsCommandList> commandList)
const {
commandList->IASetVertexBuffers(0, 1, &mVertexBufferView);
commandList->IASetIndexBuffer(&mIndexBufferView);
commandList->IASetPrimitiveTopology(mTopology);
}
void Geometry::draw(ComPtr<ID3D12GraphicsCommandList> commandList) const {
setupInputAssembler(commandList); // input assembler beállítása
commandList->DrawIndexedInstanced(mIndices.size(), 1, 0, 0, 0); // rajzolás
}
void Geometry::merge(const Geometry &other) {
std::vector<Vertex> vertices = mVertices;
vertices.insert(vertices.end(), other.mVertices.begin(), other.mVertices.end());
uint32_t offset = mIndices.size();
std::vector<uint32_t> indices = mIndices;
indices.insert(indices.end(), other.mIndices.begin(), other.mIndices.end());
// indexek megváltozatása offsettel
for (uint32_t i = offset; i < indices.size(); i++) {
indices[i] += offset;
}
// bufferek újrafoglalása a videokártyán
setVertices(vertices);
setIndices(indices);
}
Geometry &Geometry::operator+=(const Geometry &other) {
merge(other);
return *this;
}
void Geometry::loadBinarySTL(const std::string &fileName, ImportAdapter_fn * pIAD) {
auto inFile = std::ifstream(fileName, std::ios::in | std::ios::binary); // bináris fájl megnyitása olvasásra
if (!inFile.is_open()) { // megnézzük, hogy sikerült-e megnyitni a fájlt
LOG("Failed to open file: '" + fileName + "'! STL geometry loading failed!");
return;
}
// vertexek és indexek
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
uint32_t triN; // háromszögek száma
inFile.seekg(80, std::ios::beg); // fejléc átugrása
inFile.read((char *) &triN, sizeof(triN)); // háromszögek számának kiolvasása
LOG(std::to_string(sizeof(Vertex)));
// vertexek kiolvasása
for (uint32_t i = 0; i < triN; i++) {
STLTriangle triangle;
inFile.read(reinterpret_cast<char *>(&triangle), 50); // egy háromszög betöltése
for (auto& vertex : triangle.vertices)
{
if (pIAD != nullptr) {
pIAD(vertex);
}
vertices.emplace_back(vertex);
}
// indexek vektorának feltöltése
uint32_t firstIndex = 3 * i;
indices.push_back(firstIndex);
indices.push_back(firstIndex + 2);
indices.push_back(firstIndex + 1);
}
inFile.close();
setVertices(vertices);
setIndices(indices);
LOG("Successful geometry loading from file '" + fileName + "' of " + std::to_string(triN) + " triangles.");
}
ComPtr<ID3D12Device> Geometry::getDevice() const
{
return device;
}
}