#pragma once #include #include namespace Donut { struct VertexBufferElement { uint32_t type; uint32_t count; uint8_t normalized; uint32_t offset; static uint32_t get_size_of_type(uint32_t type); }; class VertexBufferLayout { public: VertexBufferLayout() = default; ~VertexBufferLayout() = default; template void push(uint32_t count) { static_assert(false); } template<> void push(uint32_t count) { m_elements.push_back({ 0x1406, count, 0, m_stride }); m_stride += count * VertexBufferElement::get_size_of_type(0x1406); } template<> void push(uint32_t count) { m_elements.push_back({ 0x1405, count, 0, m_stride }); m_stride += count * VertexBufferElement::get_size_of_type(0x1405); } template<> void push(uint32_t count) { m_elements.push_back({ 0x1401, count, 1, m_stride }); m_stride += count * VertexBufferElement::get_size_of_type(0x1401); } inline const std::vector& get_elements() const { return m_elements; } inline uint32_t get_stride() const { return m_stride; } private: std::vector m_elements; uint32_t m_stride = 0; }; class VertexBuffer { public: virtual ~VertexBuffer() = default; virtual void bind() const = 0; virtual void unbind() const = 0; virtual void set_data(const void* data, uint32_t size) = 0; virtual const VertexBufferLayout& get_layout() const = 0; virtual void set_layout(const VertexBufferLayout& layout) = 0; static VertexBuffer* create(const void* data, uint32_t size); }; };