#ifndef CLIENT_WORLD_HH_ #define CLIENT_WORLD_HH_ #include #include #include #include #include #include "client/render/render.hh" #include "client/render/texture.hh" #include "shared/player.hh" #include "shared/world.hh" namespace client { namespace world { // client::world::chunk is a renderable shared::world::chunk. class chunk : public shared::world::chunk { public: using map = std::unordered_map, decltype(&shared::world::chunk::hash), decltype(&shared::world::chunk::equal)>; // 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 chunk::map& chunks, shared::math::coords offset) const noexcept; struct glface { glm::vec3 vertice; glm::vec3 texture; }; struct glface_args { glm::vec3 translate; float rotate_degrees; glm::vec3 rotate_axis; glm::vec3 texture_offset; }; static std::array make_glfaces(const glface_args& args) noexcept; void render(const float x_offset, const float z_offset, const pass& pass) noexcept; bool maybe_regenerate_glo(const chunk::map& chunks) noexcept; public: template chunk(Args&&... args) noexcept : shared::world::chunk(std::forward(args)...) {} void draw(const map& chunks, const shared::player& lp, const pass& pass) noexcept; bool can_draw() const noexcept { return this->glo.has_value(); } }; } // namespace world } // namespace client #endif