diff --git a/src/planet/Chunk.cpp b/src/planet/Chunk.cpp index faacad6..e613906 100644 --- a/src/planet/Chunk.cpp +++ b/src/planet/Chunk.cpp @@ -60,6 +60,9 @@ Chunk::Chunk(Planet* planet, class PlanetFace* face, int x, int y, int z) : Chunk::~Chunk() { + // Delete the buffers + deleteBuffers(); + // Delete the cells for (int i = 0; i < CHUNK_SIZE; ++i) { @@ -76,6 +79,13 @@ Chunk::~Chunk() void Chunk::unload() { m_active = false; + + // Make space in memory + m_vertices.clear(); + deleteBuffers(); + + // Next time the chunk loads, we'll have to regenerate it. + m_dirty = true; } void Chunk::load() @@ -120,7 +130,7 @@ void Chunk::draw(Camera* camera, Shader* shader) shader->setBuffers(m_vao, m_vbo, 0); shader->use(); - m_model = glm::translate(glm::mat4(1.0f), this->getAbsolutePosition() + 1.0f); + m_model = glm::translate(glm::mat4(1.0f), this->getAbsolutePosition()) * m_planetFace->getOrientation(); camera->shaderViewProjection(*shader); shader->setUniform("modelMatrix", m_model); @@ -128,21 +138,24 @@ void Chunk::draw(Camera* camera, Shader* shader) glDrawArrays(GL_TRIANGLES, 0, m_vertices.size()); } -void Chunk::formFace(std::vector &vertices, glm::vec3 position, CellFace face) +void Chunk::formFace(std::vector &vertices, const glm::vec3 &position, CellFace face) { - // Positions + // Calculate positions in mesh auto P = [&](const glm::vec3& p) { const glm::vec3 pp = (position + p); return pp; }; + // Get the vertices of the selected face const glm::vec3 pos[4] = { P(FACE_VERTEX[face][0]), P(FACE_VERTEX[face][1]), P(FACE_VERTEX[face][2]), P(FACE_VERTEX[face][3]), }; + // Calculate normals glm::vec3 normal = glm::cross(pos[2] - pos[0], pos[3] - pos[1]); + // Construct face from triangles vertices.push_back({pos[0], normal, {0.0, 1.0}}); vertices.push_back({pos[1], normal, {0.0, 0.0}}); vertices.push_back({pos[2], normal, {1.0, 0.0}}); @@ -153,10 +166,16 @@ void Chunk::formFace(std::vector &vertices, glm::vec3 position, CellFace void Chunk::rebuildMesh() { - bool lDefault = true; + // Default visibility of a face + const bool faceDefault = true; + + // Don't update the chunk again until a change has occured m_dirty = false; + + // Clear previous vertices m_vertices.clear(); + // Determine which cells should have which faces drawn for (int x = 0; x < CHUNK_SIZE; x++) { for (int y = 0; y < CHUNK_SIZE; y++) @@ -168,27 +187,27 @@ void Chunk::rebuildMesh() continue; } - bool faceLeft = lDefault; + bool faceLeft = faceDefault; if(x > 0) faceLeft = !m_cells[x-1][y][z].isSolid(); - bool faceRight = lDefault; + bool faceRight = faceDefault; if(x < CHUNK_SIZE - 1) faceRight = !m_cells[x+1][y][z].isSolid(); - bool faceBottom = lDefault; + bool faceBottom = faceDefault; if(y > 0) faceBottom = !m_cells[x][y-1][z].isSolid(); - bool faceTop = lDefault; + bool faceTop = faceDefault; if(y < CHUNK_SIZE - 1) faceTop = !m_cells[x][y+1][z].isSolid(); - bool faceBack = lDefault; + bool faceBack = faceDefault; if(z > 0) faceBack = !m_cells[x][y][z-1].isSolid(); - bool faceFront = lDefault; + bool faceFront = faceDefault; if(z < CHUNK_SIZE - 1) faceFront = !m_cells[x][y][z+1].isSolid(); @@ -210,10 +229,8 @@ void Chunk::rebuildMesh() } } - if (m_vbo) - glDeleteBuffers(1, &m_vbo); - if (m_vao) - glDeleteBuffers(1, &m_vao); + // Delete previous buffers + deleteBuffers(); m_emptyChunk = m_vertices.size() == 0; @@ -227,8 +244,6 @@ void Chunk::rebuildMesh() glGenBuffers(1, &m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * m_vertices.size(), &(m_vertices[0]), GL_STATIC_DRAW); - - //std::cout << "rebuilt " << m_cx << "; " << m_cy << "; " << m_cz << "; " << std::endl; } bool Chunk::isDetailedEnough(Camera* camera) @@ -237,6 +252,14 @@ bool Chunk::isDetailedEnough(Camera* camera) return true; } +void Chunk::deleteBuffers() +{ + if (m_vbo) + glDeleteBuffers(1, &m_vbo); + if (m_vao) + glDeleteBuffers(1, &m_vao); +} + const glm::vec3 Chunk::getAbsolutePosition() { return getPosition() + m_planetFace->getPosition(); diff --git a/src/planet/Chunk.h b/src/planet/Chunk.h index e709f07..0a24b4f 100644 --- a/src/planet/Chunk.h +++ b/src/planet/Chunk.h @@ -5,7 +5,7 @@ #include "planet/Planet.h" #include "Camera.h" -#define CHUNK_SIZE 8 +#define CHUNK_SIZE 16 struct Vertex { @@ -60,7 +60,8 @@ class Chunk void draw(Camera* camera, Shader* shader); void updateFlags(); private: - void formFace(std::vector &vertices, glm::vec3 position, CellFace face); + void formFace(std::vector &vertices, const glm::vec3 &position, CellFace face); + void deleteBuffers(); Planet* m_planet; class PlanetFace* m_planetFace; diff --git a/src/planet/PlanetFace.cpp b/src/planet/PlanetFace.cpp index 720b44a..7c8dd3d 100644 --- a/src/planet/PlanetFace.cpp +++ b/src/planet/PlanetFace.cpp @@ -27,6 +27,12 @@ PlanetFace::PlanetFace(Planet* planet, const unsigned int face) : break; } m_chunks = new ChunkManager(this, planet->getRadius()); + + if (m_face < 2) + m_orientation = glm::rotate(glm::mat4(1.0f), (float)((face == FACE_BOTTOM ? 0.5 : -0.5) * M_PI), + glm::vec3(0.0f, 1.0f, 0.0f)); + else + m_orientation = glm::rotate(glm::mat4(1.0f), (float)(face * -0.5 * M_PI), glm::vec3(1.0f, 0.0f, 0.0f)); } PlanetFace::~PlanetFace() diff --git a/src/planet/PlanetFace.h b/src/planet/PlanetFace.h index d786dcb..dd4d23e 100644 --- a/src/planet/PlanetFace.h +++ b/src/planet/PlanetFace.h @@ -66,6 +66,7 @@ class PlanetFace inline Planet* getPlanet() const { return m_planet; } inline const glm::vec3 getPosition() const { return m_planet->getPosition() + m_pos; } + inline const glm::mat4 getOrientation() const { return m_orientation; } private: Planet* m_planet; unsigned int m_face; @@ -74,5 +75,7 @@ class PlanetFace glm::vec3 m_pos; ChunkManager* m_chunks; + + glm::mat4 m_orientation; }; #endif // __PLANETFACE_H__