#pragma once #include "tile-atlas.hpp" #include "tile-defs.hpp" #include #include #include #include #include #include #include "Magnum/GL/RectangleTexture.h" namespace Magnum::Examples { struct tile_shader; namespace wireframe_traits { template concept traits = requires (const T& x) { {T::num_vertices} -> std::convertible_to; {T::num_indices} -> std::convertible_to; {x.primitive} -> std::convertible_to; {x.make_vertex_positions_array() } -> std::same_as>; {x.make_index_array() } -> std::same_as>; }; struct null final { static constexpr auto primitive = GL::MeshPrimitive::Triangles; static constexpr std::size_t num_vertices = 0, num_indices = 0; static GL::RectangleTexture make_constant_texture(); static std::array make_vertex_positions_array() { return {}; } static std::array make_index_array() { return {}; } }; struct quad final { quad(Vector3 center, Vector2 size = {TILE_SIZE[0], TILE_SIZE[1]}); constexpr quad() = default; static constexpr std::size_t num_vertices = 4; static constexpr std::size_t num_indices = 0; static constexpr GL::MeshPrimitive primitive = GL::MeshPrimitive::LineLoop; using vertex_array = std::array; using index_array = std::array; vertex_array make_vertex_positions_array() const; static index_array make_index_array() { return {}; } private: Vector3 center = {}; Vector2 size = { TILE_SIZE[0], TILE_SIZE[1] }; }; } // namespace wireframe_traits template struct wireframe_mesh final { wireframe_mesh(); void draw(tile_shader& shader, T traits); private: GL::Buffer _positions_buffer{}, _texcoords_buffer{std::array{}}, _index_buffer{T::num_indices == 0 ? GL::Buffer{NoCreate} : GL::Buffer{}}; GL::RectangleTexture _texture = wireframe_traits::null::make_constant_texture(); GL::Mesh _mesh; }; extern template struct wireframe_mesh; extern template struct wireframe_mesh; } // namespace Magnum::Examples