#pragma once #include "config/types.h" #include "gfx/gl/vertexArrayObject.h" #include #include #include #include class Vertex; class MeshBase { public: void Draw() const; void DrawInstanced(GLuint vao, GLsizei count, GLuint base = 0) const; auto minExtent() const { return min; } auto maxExtent() const { return max; } protected: MeshBase(GLsizei m_numIndices, GLenum mode, std::pair minmax); glVertexArray m_vertexArrayObject; glBuffers<2> m_vertexArrayBuffers; GLsizei m_numIndices; GLenum mode; RelativePosition3D min, max; }; 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, extent(vertices)} { 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]); } static auto extent(const std::span vertices) { std::pair out {}; for (glm::length_t D {}; D < 3; ++D) { const auto mm = std::minmax_element(vertices.begin(), vertices.end(), [D](const auto & va, const auto & vb) { return va.pos[D] < vb.pos[D]; }); out.first[D] = mm.first->pos[D]; out.second[D] = mm.second->pos[D]; } return out; } }; using Mesh = MeshT;