#pragma once #include "config/types.h" #include "gfx/gl/glBuffer.h" #include #include #include #include #include class Vertex; class MeshBase { public: class Dimensions { public: using Extents1D = std::ranges::minmax_result; explicit Dimensions(std::span); RelativePosition3D minExtent, maxExtent; RelativePosition3D centre; RelativeDistance size; private: Dimensions(std::span, const std::array &); static Extents1D extents(std::span, glm::length_t); }; void draw() const; void drawInstanced(GLuint vao, GLsizei count, GLuint base = 0) const; [[nodiscard]] const Dimensions & getDimensions() const { return dimensions; } protected: MeshBase(GLsizei numIndices, GLenum mode, const std::vector &); glVertexArray vertexArrayObject; glBuffers<2> vertexArrayBuffers; GLsizei 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 & vertex) { return static_cast(vertex.pos); }))} { vertexArrayBuffers[0].storage(vertices, 0); vertexArrayBuffers[1].storage(indices, 0); configureVAO(vertexArrayObject, 0); } auto configureVAO(glVertexArray & vao, GLuint divisor) const { return vao.configure().addAttribsFor(divisor, vertexArrayBuffers[0]).addIndices(vertexArrayBuffers[1]); } }; using Mesh = MeshT;