#include "Mesh.hpp" #include 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(); }