191 lines
6.2 KiB
C++
191 lines
6.2 KiB
C++
#pragma once
|
|
|
|
#include <vector>
|
|
#include <mutex>
|
|
#include "IDrawable.h"
|
|
#include "Vertex.h"
|
|
|
|
#include <DirectXMath.h>
|
|
|
|
using namespace DirectX;
|
|
|
|
namespace eg3d {
|
|
|
|
struct STLTriangle {
|
|
XMFLOAT3 normal;
|
|
XMFLOAT3 v1, v2, v3;
|
|
uint16_t attributeByteCount;
|
|
};
|
|
|
|
class Geometry : public IDrawable {
|
|
private:
|
|
ComPtr<ID3D12Device> mDevice; // device
|
|
|
|
std::vector<Vertex> mVertices; // vertexek
|
|
std::vector<uint32_t> mIndices; // indexek
|
|
|
|
std::mutex mModifMtx; // ...
|
|
|
|
// topológia
|
|
D3D_PRIMITIVE_TOPOLOGY mTopology;
|
|
|
|
// bufferek
|
|
ComPtr<ID3D12Resource> mVertexBuffer;
|
|
ComPtr<ID3D12Resource> mIndexBuffer;
|
|
|
|
// leírók
|
|
D3D12_VERTEX_BUFFER_VIEW mVertexBufferView;
|
|
D3D12_INDEX_BUFFER_VIEW mIndexBufferView;
|
|
public:
|
|
explicit Geometry(ComPtr<ID3D12Device> 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<Vertex> &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<Vertex> getVertices() const {
|
|
return mVertices;
|
|
}
|
|
|
|
// indexek beállítása
|
|
void 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(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<uint32_t> 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<ID3D12GraphicsCommandList> commandList) const {
|
|
commandList->IASetVertexBuffers(0, 1, &mVertexBufferView);
|
|
commandList->IASetIndexBuffer(&mIndexBufferView);
|
|
commandList->IASetPrimitiveTopology(mTopology);
|
|
}
|
|
|
|
// kirajzolás
|
|
void draw(ComPtr<ID3D12GraphicsCommandList> 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<Vertex> vertices = mVertices;
|
|
vertices.insert(vertices.end(), other.mVertices.begin(), other.mVertices.end());
|
|
|
|
uint32_t offset = mIndices.size() - 1;
|
|
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 + 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<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
|
|
|
|
// 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<std::shared_ptr<Geometry>>;
|
|
}
|