#pragma once #include "GraphicsTags.hpp" #include "RcPtr.hpp" #include "SmallVector.hpp" #include #include #include #include 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, 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 elements; int vertexSize = 0; const std::vector& GetElements() { return elements; } void AddElement(VertexElementFormat element); void RemoveElement(int index); void Sort(); void CompactBindingIndex(); }; class GpuMesh : public RefCounted { public: RcPtr vertFormat; RcPtr vertBufBindings; RcPtr 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; };