Add orientation matrix to planet face, remove chunk mesh from memory when unloaded

This commit is contained in:
Evert Prants 2018-06-09 13:51:50 +03:00
parent 840e2fb46b
commit 736e7a19b1
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
4 changed files with 51 additions and 18 deletions

View File

@ -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<Vertex> &vertices, glm::vec3 position, CellFace face)
void Chunk::formFace(std::vector<Vertex> &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<Vertex> &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();

View File

@ -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<Vertex> &vertices, glm::vec3 position, CellFace face);
void formFace(std::vector<Vertex> &vertices, const glm::vec3 &position, CellFace face);
void deleteBuffers();
Planet* m_planet;
class PlanetFace* m_planetFace;

View File

@ -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()

View File

@ -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__