aboutsummaryrefslogtreecommitdiff
path: root/source/Mesh.cpp
diff options
context:
space:
mode:
authorhnOsmium0001 <[email protected]>2022-04-08 22:30:12 -0700
committerhnOsmium0001 <[email protected]>2022-04-08 22:30:12 -0700
commite47a98793e58a5dbbe76bfed27e59408e43538e4 (patch)
tree250eb4c4200efb63c493ac6f4adb83c89be10ea1 /source/Mesh.cpp
parent3fdc6eb4f2cbeffce9b250beec4d3a2d52a3f534 (diff)
More work
Diffstat (limited to 'source/Mesh.cpp')
-rw-r--r--source/Mesh.cpp193
1 files changed, 193 insertions, 0 deletions
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 <algorithm>
+
+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();
+}