From e47a98793e58a5dbbe76bfed27e59408e43538e4 Mon Sep 17 00:00:00 2001 From: hnOsmium0001 Date: Fri, 8 Apr 2022 22:30:12 -0700 Subject: More work --- source/Mesh.cpp | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) (limited to 'source/Mesh.cpp') diff --git a/source/Mesh.cpp b/source/Mesh.cpp index 3b0ee1f..385ef55 100644 --- a/source/Mesh.cpp +++ b/source/Mesh.cpp @@ -1 +1,194 @@ #include "Mesh.hpp" + +#include + +int Tags::SizeOf(VertexElementType type) { + switch (type) { + case VET_Float1: + return sizeof(float); + case VET_Float2: + return sizeof(float) * 2; + case VET_Float3: + return sizeof(float) * 3; + case VET_Float4: + return sizeof(float) * 4; + case VET_Double1: + return sizeof(double); + case VET_Double2: + return sizeof(double) * 2; + case VET_Double3: + return sizeof(double) * 3; + case VET_Double4: + return sizeof(double) * 4; + case VET_Short2: + case VET_Short2Norm: + case VET_Ushort2: + case VET_Ushort2Norm: + return sizeof(short) * 2; + case VET_Short4: + case VET_Short4Norm: + case VET_Ushort4: + case VET_Ushort4Norm: + return sizeof(short) * 4; + case VET_Int1: + case VET_Uint1: + return sizeof(int); + case VET_Int2: + case VET_Uint2: + return sizeof(int) * 2; + case VET_Int3: + case VET_Uint3: + return sizeof(int) * 3; + case VET_Int4: + case VET_Uint4: + return sizeof(int) * 4; + case VET_Byte4: + case VET_Byte4Norm: + case VET_Ubyte4: + case VET_Ubyte4Norm: + return sizeof(char) * 4; + } + return 0; +} + +bool Tags::IsNormalized(VertexElementType type) { + return type >= VET_NORM_BEGIN && type <= VET_NORM_END; +} + +int Tags::SizeOf(IndexType type) { + switch (type) { + case IT_16Bit: return sizeof(uint16_t); + case IT_32Bit: return sizeof(uint32_t); + } + return 0; +} + +GpuVertexBuffer::GpuVertexBuffer() { + glGenBuffers(1, &handle); +} + +GpuVertexBuffer::~GpuVertexBuffer() { + glDeleteBuffers(1, &handle); +} + +void GpuVertexBuffer::Upload(const std::byte* data, size_t sizeInBytes) { + glBindBuffer(GL_ARRAY_BUFFER, handle); + glBufferData(GL_ARRAY_BUFFER, sizeInBytes, data, GL_DYNAMIC_DRAW); +} + +GpuIndexBuffer::GpuIndexBuffer() { + glGenBuffers(1, &handle); +} + +GpuIndexBuffer::~GpuIndexBuffer() { + glDeleteBuffers(1, &handle); +} + +void GpuIndexBuffer::Upload(const std::byte* data, size_t count) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * Tags::SizeOf(indexType), data, GL_DYNAMIC_DRAW); +} + +void GpuIndexBuffer::Upload(const std::byte* data, Tags::IndexType type, size_t count) { + indexType = type; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * Tags::SizeOf(type), data, GL_DYNAMIC_DRAW); +} + +int BufferBindings::GetMaxBindingIndex() const { + return bindings.size() - 1; +} + +GpuVertexBuffer* BufferBindings::GetBinding(int index) const { + if (index >= 0 && index < bindings.size()) { + return bindings[index].Get(); + } else { + return nullptr; + } +} + +void BufferBindings::SetBinding(int index, GpuVertexBuffer* buffer) { + int maxBindingIndex = GetMaxBindingIndex(); + if (index > maxBindingIndex) { + int countDelta = index - maxBindingIndex; + bindings.resize(bindings.size() + countDelta); + } + + bindings[index].Attach(buffer); + if (index == maxBindingIndex && buffer == nullptr) { + bindings.pop_back(); + } +} + +void BufferBindings::Clear() { + bindings.clear(); +} + +int VertexElementFormat::GetStride() const { + return Tags::SizeOf(type); +} + +void VertexFormat::AddElement(VertexElementFormat element) { + vertexSize += element.GetStride(); + elements.push_back(std::move(element)); +} + +void VertexFormat::RemoveElement(int index) { + auto& element = elements[index]; + vertexSize -= element.GetStride(); + elements.erase(elements.begin() + index); +} + +void VertexFormat::Sort() { + std::sort(elements.begin(), elements.end()); +} + +void VertexFormat::CompactBindingIndex() { + if (elements.empty()) { + return; + } + + Sort(); + + int targetIdx = 0; + int lastIdx = elements[0].bindingIndex; + int c = 0; + for (auto& elm : elements) { + if (lastIdx != elm.bindingIndex) { + targetIdx++; + lastIdx = elm.bindingIndex; + } + if (targetIdx != elm.bindingIndex) { + elements[c] = elm; + elements[c].bindingIndex = targetIdx; + } + ++c; + } +} + +GpuMesh::GpuMesh(VertexFormat* vertexFormat, BufferBindings* bindings, GpuIndexBuffer* indexBuffer) + : vertFormat(vertexFormat) + , vertBufBindings(bindings) + , indexBuf(indexBuffer) { +} + +bool GpuMesh::IsEmpty() const { + return vertFormat != nullptr; +} + +void GpuMesh::SetVertex(VertexFormat* vertexFormat, BufferBindings* bindings) { + vertFormat.Attach(vertexFormat); + vertBufBindings.Attach(bindings); +} + +VertexFormat* GpuMesh::GetVertexFormat() const { + return vertFormat.Get(); +} + +BufferBindings* GpuMesh::GetVertexBufferBindings() const { + return vertBufBindings.Get(); +} + +GpuIndexBuffer* GpuMesh::GetIndexBuffer() const { + return indexBuf.Get(); +} -- cgit v1.2.3-70-g09d2