diff options
author | hnOsmium0001 <[email protected]> | 2022-04-08 22:30:12 -0700 |
---|---|---|
committer | hnOsmium0001 <[email protected]> | 2022-04-08 22:30:12 -0700 |
commit | e47a98793e58a5dbbe76bfed27e59408e43538e4 (patch) | |
tree | 250eb4c4200efb63c493ac6f4adb83c89be10ea1 /source/Mesh.hpp | |
parent | 3fdc6eb4f2cbeffce9b250beec4d3a2d52a3f534 (diff) |
More work
Diffstat (limited to 'source/Mesh.hpp')
-rw-r--r-- | source/Mesh.hpp | 155 |
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; }; |