aboutsummaryrefslogtreecommitdiff
path: root/source/Mesh.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Mesh.hpp')
-rw-r--r--source/Mesh.hpp155
1 files changed, 147 insertions, 8 deletions
diff --git a/source/Mesh.hpp b/source/Mesh.hpp
index d383087..a208eda 100644
--- a/source/Mesh.hpp
+++ b/source/Mesh.hpp
@@ -1,17 +1,156 @@
#pragma once
-#include "PodVector.hpp"
#include "RcPtr.hpp"
+#include "SmallVector.hpp"
+#include <glad/glad.h>
+#include <cstddef>
#include <cstdint>
+#include <vector>
-struct MeshVertex {
- float x, y, z;
- float u, v;
- uint8_t r, g, b, a;
+namespace Tags {
+/// Vertex element semantics, used to identify the meaning of vertex buffer contents
+enum VertexElementSemantic {
+ /// Position, typically VET_Float3
+ VES_Position = 1,
+ /// Blending weights
+ VES_BlendWeights = 2,
+ /// Blending indices
+ VES_BlendIndices = 3,
+ /// Normal, typically VET_Float3
+ VES_Normal = 4,
+ /// Colour, typically VET_Ubyte4
+ VES_Colour = 5,
+ /// Secondary colour. Generally free for custom data. Means specular with OpenGL FFP.
+ VES_Colour2 = 6,
+ /// Texture coordinates, typically VET_Float2
+ VES_Texture_coordinates = 7,
+ /// Binormal (Y axis if normal is Z)
+ VES_Binormal = 8,
+ /// Tangent (X axis if normal is Z)
+ VES_Tangent = 9,
+ /// The number of VertexElementSemantic elements (note - the first value VES_Position is 1)
+ VES_COUNT = 9,
};
-class Mesh : public RefCounted {
-private:
- PodVector<MeshVertex> mVertex;
+enum VertexElementType {
+ VET_Float1,
+ VET_Float2,
+ VET_Float3,
+ VET_Float4,
+
+ VET_Short2,
+ VET_Short4,
+ VET_Ubyte4,
+
+ // the following are not universally supported on all hardware:
+ VET_Double1,
+ VET_Double2,
+ VET_Double3,
+ VET_Double4,
+ VET_Ushort2,
+ VET_Ushort4,
+ VET_Int1,
+ VET_Int2,
+ VET_Int3,
+ VET_Int4,
+ VET_Uint1,
+ VET_Uint2,
+ VET_Uint3,
+ VET_Uint4,
+ VET_Byte4, /// signed bytes
+
+ VET_NORM_BEGIN,
+ VET_Byte4Norm = VET_NORM_BEGIN, /// signed bytes (normalized to -1..1)
+ VET_Ubyte4Norm, /// unsigned bytes (normalized to 0..1)
+ VET_Short2Norm, /// signed shorts (normalized to -1..1)
+ VET_Short4Norm,
+ VET_Ushort2Norm, /// unsigned shorts (normalized to 0..1)
+ VET_Ushort4Norm,
+ VET_NORM_END = VET_Ushort4Norm,
+};
+
+int SizeOf(VertexElementType type);
+bool IsNormalized(VertexElementType type);
+
+enum IndexType {
+ IT_16Bit,
+ IT_32Bit,
+};
+
+int SizeOf(IndexType type);
+} // namespace Tags
+
+struct GpuVertexBuffer : public RefCounted {
+ GLuint handle;
+ int sizeInBytes;
+
+ GpuVertexBuffer();
+ ~GpuVertexBuffer();
+
+ void Upload(const std::byte* data, size_t sizeInBytes);
+};
+
+struct GpuIndexBuffer : public RefCounted {
+ GLuint handle;
+ Tags::IndexType indexType;
+ int sizeInBytes;
+
+ GpuIndexBuffer();
+ ~GpuIndexBuffer();
+
+ void Upload(const std::byte* data, size_t count);
+ void Upload(const std::byte* data, Tags::IndexType type, size_t count);
+};
+
+struct BufferBindings : public RefCounted {
+ SmallVector<RcPtr<GpuVertexBuffer>, 4> bindings;
+
+ int GetMaxBindingIndex() const;
+
+ /// Safe. Returns nullptr if the index is not bound to any buffers.
+ GpuVertexBuffer* GetBinding(int index) const;
+ /// Adds or updates a buffer binding. Setting a binding to nullptr effectively removes the binding.
+ void SetBinding(int index, GpuVertexBuffer* buffer);
+ void Clear();
+};
+
+struct VertexElementFormat {
+ int offset;
+ int bindingIndex;
+ Tags::VertexElementType type;
+ Tags::VertexElementSemantic semantic;
+
+ int GetStride() const;
+
+ auto operator<=>(const VertexElementFormat&) const = default;
+};
+
+struct VertexFormat : public RefCounted {
+ std::vector<VertexElementFormat> elements;
+ int vertexSize = 0;
+
+ const std::vector<VertexElementFormat>& GetElements() { return elements; }
+ void AddElement(VertexElementFormat element);
+ void RemoveElement(int index);
+
+ void Sort();
+ void CompactBindingIndex();
+};
+
+class GpuMesh : public RefCounted {
+public:
+ RcPtr<VertexFormat> vertFormat;
+ RcPtr<BufferBindings> vertBufBindings;
+ RcPtr<GpuIndexBuffer> indexBuf;
+
+public:
+ GpuMesh(VertexFormat* vertexFormat, BufferBindings* bindings, GpuIndexBuffer* indexBuffer);
+
+ bool IsEmpty() const;
+ void SetVertex(VertexFormat* vertexFormat, BufferBindings* bindings);
+ VertexFormat* GetVertexFormat() const;
+ BufferBindings* GetVertexBufferBindings() const;
+ void SetIndex(GpuIndexBuffer* buffer);
+ GpuIndexBuffer* GetIndexBuffer() const;
};