#pragma once #include "config/types.h" #include "gfx/gl/vertexArrayObject.h" #include #include #include #include #include class Vertex; class MeshBase { public: class Dimensions { public: using Extents1D = std::ranges::minmax_result; explicit Dimensions(const std::span); RelativePosition3D minExtent, maxExtent; RelativePosition3D centre; RelativeDistance size; private: Dimensions(const std::span, const std::array &); static Extents1D extents(const std::span, glm::length_t D); }; void Draw() const; void DrawInstanced(GLuint vao, GLsizei count, GLuint base = 0) const; [[nodiscard]] const Dimensions & getDimensions() const { return dimensions; } protected: MeshBase(GLsizei m_numIndices, GLenum mode, const std::vector &); glVertexArray m_vertexArrayObject; glBuffers<2> m_vertexArrayBuffers; GLsizei m_numIndices; GLenum mode; Dimensions dimensions; }; template class MeshT : public MeshBase, public ConstTypeDefs> { public: MeshT(const std::span vertices, const std::span indices, GLenum mode = GL_TRIANGLES) : MeshBase {static_cast(indices.size()), mode, materializeRange(vertices | std::views::transform([](const auto & v) { return static_cast(v.pos); }))} { VertexArrayObject::data(vertices, m_vertexArrayBuffers[0], GL_ARRAY_BUFFER); VertexArrayObject::data(indices, m_vertexArrayBuffers[1], GL_ARRAY_BUFFER); configureVAO(m_vertexArrayObject); } VertexArrayObject & configureVAO(VertexArrayObject && vao) const { return vao.addAttribsFor(m_vertexArrayBuffers[0]).addIndices(m_vertexArrayBuffers[1]); } }; using Mesh = MeshT;