#pragma once #include #include #include "IDrawable.h" #include "Vertex.h" #include using namespace DirectX; namespace eg3d { struct STLTriangle { XMFLOAT3 normal; XMFLOAT3 v1, v2, v3; uint16_t attributeByteCount; }; class Geometry : public IDrawable { private: ComPtr mDevice; // device std::vector mVertices; // vertexek std::vector mIndices; // indexek std::mutex mModifMtx; // ... // topológia D3D_PRIMITIVE_TOPOLOGY mTopology; // bufferek ComPtr mVertexBuffer; ComPtr mIndexBuffer; // leírók D3D12_VERTEX_BUFFER_VIEW mVertexBufferView; D3D12_INDEX_BUFFER_VIEW mIndexBufferView; public: explicit Geometry(ComPtr device) : mDevice(device) { // topológia beállítása setTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); } // másolókonstruktor Geometry(const Geometry& other) : mDevice(other.mDevice) { setTopology(other.getTopology()); setVertices(other.getVertices()); setIndices(other.getIndices()); } // vertexek beállítása void setVertices(const std::vector &vertices) { mVertices = vertices; size_t bufferSize = mVertices.size() * sizeof(Vertex); // buffer mérete mVertexBuffer.Reset(); // buffer törlése mVertexBuffer = createBuffer_UH(mDevice, 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; } // vertexek lekérése std::vector getVertices() const { return mVertices; } // indexek beállítása void setIndices(const std::vector &indices) { mIndices = indices; size_t bufferSize = mIndices.size() * sizeof(uint32_t); // buffer mérete mIndexBuffer.Reset(); // buffer törlése mIndexBuffer = createBuffer_UH(mDevice, 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; } // indexek lekérése std::vector getIndices() const { return mIndices; } // topológia beállítása void setTopology(D3D_PRIMITIVE_TOPOLOGY topology) { mTopology = topology; } // topológia beállítása D3D_PRIMITIVE_TOPOLOGY getTopology() const { return mTopology; } void loadFromFile(const std::string& fileName) { // TODO Epagrisnak: Assimpot le kell fordítani mindenkinek! } // input assembler beállítása void setupInputAssembler(ComPtr commandList) const { commandList->IASetVertexBuffers(0, 1, &mVertexBufferView); commandList->IASetIndexBuffer(&mIndexBufferView); commandList->IASetPrimitiveTopology(mTopology); } // kirajzolás void draw(ComPtr commandList) const override { setupInputAssembler(commandList); // input assembler beállítása commandList->DrawIndexedInstanced(mIndices.size(), 1, 0, 0, 0); // rajzolás } // két geometria egyesítése Geometry& operator+=(const Geometry& other) { std::vector vertices = mVertices; vertices.insert(vertices.end(), other.mVertices.begin(), other.mVertices.end()); uint32_t offset = mIndices.size() - 1; std::vector indices = mIndices; indices.insert(indices.end(), other.mIndices.begin(), other.mIndices.end()); // indexek megváltozatása offsettel for (uint32_t i = offset + 1; i < indices.size(); i++) { indices[i] += offset; } // bufferek újrafoglalása a videokártyán setVertices(vertices); setIndices(indices); return *this; } // bináris STL fájl betöltése void loadBinarySTL(const std::string& fileName) { 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 vertices; std::vector 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 // vertexek kiolvasása for (uint32_t i = 0; i < triN; i++) { STLTriangle triangle; inFile.read((char *)&triangle, sizeof(triangle)); // egy háromszög betöltése vertices.push_back(triangle.v1); vertices.push_back(triangle.v2); vertices.push_back(triangle.v3); // indexek vektorának feltöltése uint32_t firstIndex = 3 * i; indices.push_back(firstIndex); indices.push_back(firstIndex + 1); indices.push_back(firstIndex + 2); } inFile.close(); setVertices(vertices); setIndices(indices); LOG("Successful geometry loading from file '" + fileName + "' of " + std::to_string(triN) + " triangles."); } }; // geometriatároló típusa using GeometryPool = std::vector>; }