181 lines
5.5 KiB
C++
181 lines
5.5 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& stlVertex : triangle.vertices)
|
|
{
|
|
if (pIAD != nullptr) {
|
|
pIAD(stlVertex);
|
|
}
|
|
|
|
// koordináták másolása
|
|
Vertex vertex = stlVertex;
|
|
|
|
// normálvektorok hozzárendelése TODO szebben!
|
|
vertex.nx = triangle.normal.x;
|
|
vertex.ny = triangle.normal.y;
|
|
vertex.nz = triangle.normal.z;
|
|
|
|
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;
|
|
}
|
|
}
|