#ifndef FAN_MESH_HPP_ #define FAN_MESH_HPP_ #include #include #include "vertex.hpp" #include "material.hpp" #include "utils.hpp" namespace Fan { class Mesh { public: // A range drawn with one material. Offset and count are in indices, or in // vertices if the mesh has no index buffer struct SubMesh { GLuint index_offset{}; GLuint index_count{}; Rc material{}; }; // Without indices the vertices are drawn in order. Without submeshes a single // one with no material covers the whole mesh static Rc create(const std::vector& vertices, const std::vector& indices = {}, const std::vector& submeshes = {}); // Unit cube centered at the origin, with normals and texture coordinates static Rc create_cube(); Mesh(const std::vector& vertices, const std::vector& indices, const std::vector& submeshes, bool has_indices, GLuint VBO, GLuint VAO, GLuint EBO) : m_vertices(vertices) , m_indices(indices) , m_submeshes(submeshes) , m_has_indices(has_indices) , m_VBO(VBO) , m_VAO(VAO) , m_EBO(EBO) {} ~Mesh(); Mesh(const Mesh&) = delete; Mesh& operator=(const Mesh&) = delete; Mesh(Mesh&& other) noexcept; Mesh& operator=(Mesh&& other) noexcept; const std::vector& get_submeshes() const; // Geometry only: the caller binds the shader and material first void draw() const; void draw_submesh(GLuint index_offset, GLuint index_count) const; private: std::vector m_vertices{}; std::vector m_indices{}; std::vector m_submeshes{}; bool m_has_indices{}; GLuint m_VBO{}; GLuint m_VAO{}; GLuint m_EBO{}; }; } // namespace Fan #endif // FAN_MESH_HPP_