#ifndef CLIENT_WORLD_CHUNK_HH_ #define CLIENT_WORLD_CHUNK_HH_ #include #include #include #include #include #include "client/render/render.hh" #include "client/render/texture.hh" #include "client/world/block.hh" #include "shared/entity/player.hh" #include "shared/world/chunk.hh" namespace client { namespace world { class chunk; using chunks_t = std::unordered_map, decltype(&shared::world::chunk::hash), decltype(&shared::world::chunk::equal)>; // client::world::chunk is a renderable shared::world::chunk. class chunk : public shared::world::chunk { public: // Which part to draw when we call draw. enum class pass { solid, water }; public: bool should_regenerate_vbo; private: struct gl_objects { unsigned long solid_elements; GLuint solid_vbo; GLuint solid_vao; unsigned long water_elements; GLuint water_vbo; GLuint water_vao; gl_objects(const unsigned long se, const GLuint svbo, const GLuint svao, const unsigned long we, const GLuint wvbo, const GLuint wvao) : solid_elements(se), solid_vbo(svbo), solid_vao(svao), water_elements(we), water_vbo(wvbo), water_vao(wvao) {} gl_objects(const gl_objects&) = delete; gl_objects(gl_objects&&) = delete; ~gl_objects() { glDeleteBuffers(1, &solid_vbo); glDeleteVertexArrays(1, &solid_vao); glDeleteBuffers(1, &water_vbo); glDeleteVertexArrays(1, &water_vao); } }; std::optional glo; private: const chunk* get_neighbour(const chunks_t& chunks, shared::math::coords offset) const noexcept; void render(const float x_offset, const float z_offset, const pass& pass) noexcept; bool maybe_regenerate_glo(const chunks_t& chunks) noexcept; public: template chunk(Args&&... args) noexcept : shared::world::chunk(std::forward(args)...) {} virtual ~chunk() noexcept = default; // true if we regen'd, false otherwise bool draw(const chunks_t& chunks, const shared::player& lp, const pass& pass, const bool skip_regen = false) noexcept; bool can_draw() const noexcept { return this->glo.has_value(); } }; } // namespace world } // namespace client #endif