#include #include "chunk.hpp" #include "tile/tile_base.hpp" #include "../graphics/texture.hpp" #include #include #include #include #include #include using World::Chunk; using World::Tile::TileBase; constexpr glm::vec<2, int> get_pos_mod(glm::vec<2, int> pos) { return (pos % Chunk::N + Chunk::N) % Chunk::N; } Chunk::Chunk(glm::vec<2, int> pos) { m_pos = pos; } TileBase* Chunk::get(glm::vec<2, int> p) { p = get_pos_mod(p); return m_tiles[p.x * N + p.y].get(); } const TileBase* Chunk::get(glm::vec<2, int> p) const { p = get_pos_mod(p); return m_tiles[p.x * N + p.y].get(); } TileBase* Chunk::set(glm::vec<2, int> p, std::unique_ptr v) { TileBase* r = v.get(); p = get_pos_mod(p); m_tiles[p.x * N + p.y].swap(v); if(r && !v) { m_used_tiles += 1; } else if(!r && v) { m_used_tiles -= 1; } m_dirty = true; return r; } void Chunk::update(Map& map) { for(auto& tile : m_tiles) { if(tile) { tile->update(); } } if(!m_dirty) { return; } Graphics::Mesh mesh; const Chunk* chunks[4] = { map.get_chunk(m_pos + glm::vec<2, int>(N, 0)), map.get_chunk(m_pos + glm::vec<2, int>(0, N)), map.get_chunk(m_pos + glm::vec<2, int>(-N, 0)), map.get_chunk(m_pos + glm::vec<2, int>(0, -N)), }; const glm::vec<2, int> neighbours[4] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1}, }; for(int x = 0; x < N; x++) { for(int y = 0; y < N; y++) { glm::vec<2, int> t_off(x, y); if(!get(t_off)) { continue; } auto prim = PRIMITIVE_B; prim.m_offset = {t_off, 0, 0}; prim.m_texid = Graphics::Texture::YELLOW_BRICK_FLOOR; mesh.add_primitive(prim); for(int i = 0; i < std::size(neighbours); i++) { glm::vec<2, int> n_off = neighbours[i] + t_off; const Chunk* chunk_check = this; if(n_off.x == N) { chunk_check = chunks[0]; } else if(n_off.y == N) { chunk_check = chunks[1]; } else if(n_off.x == -1) { chunk_check = chunks[2]; } else if(n_off.y == -1) { chunk_check = chunks[3]; } if(!chunk_check || !chunk_check->get(n_off)) { prim = PRIMITIVE_S[i]; prim.m_offset = {t_off, 0, 0}; prim.m_texid = Graphics::Texture::YELLOW_BRICK_WALL; mesh.add_primitive(prim); } } } } m_model.set(mesh, GL_DYNAMIC_DRAW); m_dirty = false; } void Chunk::render(const Graphics::Context& ctx) const { ctx.set_model_matrix(glm::translate(glm::mat4(1), {glm::vec<2, double>(m_pos) - ctx.m_transform, 0})); ctx.set_colour_matrix(glm::mat4(1)); m_model.render(GL_TRIANGLES); for(auto& tile : m_tiles) { if(tile) { tile->render(); } } }