it's.. something..

This commit is contained in:
Evert Prants 2018-06-06 21:11:17 +03:00
parent 989d402933
commit 47fe269c76
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
11 changed files with 667 additions and 81 deletions

7
data/shaders/chunk.frag Normal file
View File

@ -0,0 +1,7 @@
#version 110
varying vec2 uv_p;
void main(void) {
gl_FragColor = vec4(uv_p.xy, 0.5f, 1.0f);
}

16
data/shaders/chunk.vert Normal file
View File

@ -0,0 +1,16 @@
#version 110
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
varying vec2 uv_p;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
void main(void) {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
uv_p = vec2(clamp(uv.x + normal.x, 0.0, 1.0), uv.y);
}

View File

@ -224,7 +224,15 @@ void Application::run()
glEnable(GL_DEPTH_TEST);
Planet* pl = new Planet(glm::vec3(0.0f,0.0f,0.0f), 20);
Planet* pl = new Planet(glm::vec3(0.0f,0.0f,0.0f), 10);
// Create the shader and link them together
Shader& chunkShader = Shader::createShader("data/shaders/chunk.vert", "data/shaders/chunk.frag");
chunkShader.linkShaders();
// Set attribute arrays
chunkShader.setAttribute("position", 3, GL_FALSE, 8, 0, GL_FLOAT);
chunkShader.setAttribute("normal", 3, GL_TRUE, 8, 3, GL_FLOAT);
chunkShader.setAttribute("uv", 2, GL_FALSE, 8, 6, GL_FLOAT);
// END TEST CODE
@ -252,12 +260,19 @@ void Application::run()
glDrawArrays(GL_TRIANGLES, 0, 12*3); // 12*3 indices starting at 0 -> 12 triangles -> 6 squares
pl->tick(m_camera, deltaTime);
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
pl->draw(m_camera, &chunkShader);
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
// END TEST CODE
update(deltaTime);
pl->tick(deltaTime);
render();
pl->draw(m_camera);
// Update window with OpenGL rendering
SDL_GL_SwapWindow(m_window);

View File

@ -61,9 +61,9 @@ glm::mat4 Camera::getViewMatrix()
return glm::lookAt(m_position, m_position + m_front, m_up);
}
void Camera::updateFrustum(void)
void Camera::updateFrustum(glm::mat4 modelMatrix)
{
const glm::mat4 mvp = getViewMatrix() * m_projection;
const glm::mat4 mvp = getViewMatrix() * m_projection * modelMatrix;
// Extract the clipping planes; right, left, far, near, top, bottom
m_planes[0] = mvp[3] - mvp[0];
@ -227,7 +227,6 @@ void Camera::updateProjection(void)
// Recalculate the projection matrix
glm::vec2 screenDims = Application::getInstance().getScreenDimensions();
m_projection = glm::perspective(getFOV(), (GLfloat)screenDims.x/(GLfloat)screenDims.y, 0.1f, 100.0f);
updateFrustum();
}
void Camera::updateCameraVectors(void)
@ -243,6 +242,4 @@ void Camera::updateCameraVectors(void)
// Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
m_right = glm::normalize(glm::cross(m_front, m_worldUp));
m_up = glm::normalize(glm::cross(m_right, m_front));
updateFrustum();
}

View File

@ -57,6 +57,8 @@ public:
int frustumContainsSphere(const glm::vec3 &position, const double radius) const;
int frustumContainsBox(const glm::vec3 &min, const glm::vec3 &max) const;
int frustumContainsPolygon(const std::vector<glm::vec3> &points) const;
void updateFrustum(glm::mat4 modelMatrix);
private:
glm::vec3 m_position;
glm::vec3 m_front;
@ -83,6 +85,5 @@ private:
void updateCameraVectors(void);
void updateProjection(void);
void updateFrustum(void);
};
#endif // __CAMERA_H__

View File

@ -1,6 +1,51 @@
#include "Chunk.h"
#include "planet/PlanetFace.h"
const glm::vec3 FACE_VERTEX[6][4] = {
// Bottom
{
glm::vec3(1.0, 0.0, 0.0),
glm::vec3(1.0, 0.0, 1.0),
glm::vec3(0.0, 0.0, 1.0),
glm::vec3(0.0, 0.0, 0.0)
},
// Top
{
glm::vec3(0.0, 1.0, 0.0),
glm::vec3(0.0, 1.0, 1.0),
glm::vec3(1.0, 1.0, 1.0),
glm::vec3(1.0, 1.0, 0.0)
},
// Left
{
glm::vec3(0.0, 0.0, 1.0),
glm::vec3(0.0, 1.0, 1.0),
glm::vec3(0.0, 1.0, 0.0),
glm::vec3(0.0, 0.0, 0.0)
},
// Right
{
glm::vec3(1.0, 0.0, 0.0),
glm::vec3(1.0, 1.0, 0.0),
glm::vec3(1.0, 1.0, 1.0),
glm::vec3(1.0, 0.0, 1.0)
},
// Back
{
glm::vec3(1.0, 0.0, 1.0),
glm::vec3(1.0, 1.0, 1.0),
glm::vec3(0.0, 1.0, 1.0),
glm::vec3(0.0, 0.0, 1.0)
},
// Front
{
glm::vec3(0.0, 0.0,0.0),
glm::vec3(0.0, 1.0,0.0),
glm::vec3(1.0, 1.0,0.0),
glm::vec3(1.0, 0.0,0.0)
}
};
Chunk::Chunk(Planet* planet, class PlanetFace* face, int x, int y, int z) :
m_planet(planet),
m_planetFace(face),
@ -10,40 +55,189 @@ Chunk::Chunk(Planet* planet, class PlanetFace* face, int x, int y, int z) :
m_dirty(false),
m_active(true)
{
// Create cells
for(int i=0;i<CHUNK_N;i++)
{
for(int j=0;j<CHUNK_N;j++)
{
for(int k=0;k<CHUNK_N;k++)
{
m_cells[i][j][k] = new Cell();
}
}
}
}
Chunk::~Chunk()
{
for(int i=0;i<CHUNK_N;i++)
for(int j=0;j<CHUNK_N;j++)
for(int k=0;k<CHUNK_N;k++)
if(m_cells[i][j][k])
delete m_cells[i][j][k];
// Delete the cells
for (int i = 0; i < CHUNK_SIZE; ++i)
{
for (int j = 0; j < CHUNK_SIZE; ++j)
{
delete [] m_cells[i][j];
}
delete [] m_cells[i];
}
delete [] m_cells;
}
void Chunk::destroyChunk()
void Chunk::unload()
{
m_active = false;
delete this;
}
void Chunk::tick(GLfloat dtime)
void Chunk::load()
{
if (!m_active) return;
m_active = true;
}
void Chunk::draw(Camera* camera)
void Chunk::generate()
{
if (!m_active) return;
// Populate cells with dummy data
m_cells = new Cell**[CHUNK_SIZE];
for(int i = 0; i < CHUNK_SIZE; i++)
{
m_cells[i] = new Cell*[CHUNK_SIZE];
for(int j = 0; j < CHUNK_SIZE; j++)
{
m_cells[i][j] = new Cell[CHUNK_SIZE];
}
}
m_generated = true;
m_dirty = true;
}
void Chunk::updateFlags()
{
// Figure out if we are a completely empty chunk
//if(numVerts == 0 && numTriangles == 0)
//{
// m_emptyChunk = true;
//}
//m_emptyChunk = false;
}
void Chunk::draw(Camera* camera, Shader* shader)
{
if (!m_active || !m_vao || !m_vbo)
return;
shader->setBuffers(m_vao, m_vbo, 0);
shader->use();
m_model = glm::translate(glm::mat4(1.0f), this->getAbsolutePosition() + 1.0f);
camera->shaderViewProjection(*shader);
shader->setUniform("modelMatrix", m_model);
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
}
void Chunk::formFace(std::vector<Vertex> &vertices, glm::vec3 position, CellFace face)
{
// Positions
auto P = [&](const glm::vec3& p) {
const glm::vec3 pp = (position + p);
return pp;
};
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]),
};
glm::vec3 normal = glm::cross(pos[2] - pos[0], pos[3] - pos[1]);
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}});
vertices.push_back({pos[0], normal, {0.0, 1.0}});
vertices.push_back({pos[2], normal, {1.0, 0.0}});
vertices.push_back({pos[3], normal, {1.0, 1.0}});
}
void Chunk::rebuildMesh()
{
bool lDefault = true;
m_dirty = false;
m_vertices.clear();
for (int x = 0; x < CHUNK_SIZE; x++)
{
for (int y = 0; y < CHUNK_SIZE; y++)
{
for (int z = 0; z < CHUNK_SIZE; z++)
{
if(m_cells[x][y][z].isSolid() == false)
{
continue;
}
bool faceLeft = lDefault;
if(x > 0)
faceLeft = !m_cells[x-1][y][z].isSolid();
bool faceRight = lDefault;
if(x < CHUNK_SIZE - 1)
faceRight = !m_cells[x+1][y][z].isSolid();
bool faceBottom = lDefault;
if(y > 0)
faceBottom = !m_cells[x][y-1][z].isSolid();
bool faceTop = lDefault;
if(y < CHUNK_SIZE - 1)
faceTop = !m_cells[x][y+1][z].isSolid();
bool faceBack = lDefault;
if(z > 0)
faceBack = !m_cells[x][y][z-1].isSolid();
bool faceFront = lDefault;
if(z < CHUNK_SIZE - 1)
faceFront = !m_cells[x][y][z+1].isSolid();
glm::vec3 cellPos = glm::vec3(x, y, z);
if (faceBottom)
formFace(m_vertices, cellPos, CELL_FACE_BOTTOM);
if (faceTop)
formFace(m_vertices, cellPos, CELL_FACE_TOP);
if (faceLeft)
formFace(m_vertices, cellPos, CELL_FACE_LEFT);
if (faceRight)
formFace(m_vertices, cellPos, CELL_FACE_RIGHT);
if (faceFront)
formFace(m_vertices, cellPos, CELL_FACE_FRONT);
if (faceBack)
formFace(m_vertices, cellPos, CELL_FACE_BACK);
}
}
}
if (m_vbo)
glDeleteBuffers(1, &m_vbo);
if (m_vao)
glDeleteBuffers(1, &m_vao);
m_emptyChunk = m_vertices.size() == 0;
if (m_emptyChunk)
return;
// Generate buffers
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
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)
{
// TODO: Level of detail on mesh
return true;
}
const glm::vec3 Chunk::getAbsolutePosition()
{
return getPosition() + m_planetFace->getPosition();
}

View File

@ -5,12 +5,28 @@
#include "planet/Planet.h"
#include "Camera.h"
#define CHUNK_N 32
#define CHUNK_SIZE 8
struct Vertex
{
glm::vec3 position;
glm::vec3 normal;
glm::vec2 uv;
};
struct Cell
{
glm::vec3 position;
GLuint internalId;
bool isSolid()
{
return true;
}
};
enum CellFace {
CELL_FACE_BOTTOM, CELL_FACE_TOP,
CELL_FACE_LEFT, CELL_FACE_RIGHT,
CELL_FACE_FRONT, CELL_FACE_BACK
};
class Chunk
@ -19,21 +35,47 @@ class Chunk
Chunk(Planet* planet, class PlanetFace* face, int x, int y, int z);
~Chunk();
void destroyChunk();
void unload();
void load();
void generate();
void tick(GLfloat dtime);
void draw(Camera* camera);
void rebuildMesh();
inline const glm::vec3 getPosition() const { return glm::vec3(m_cx, m_cy, m_cz); }
const glm::vec3 getAbsolutePosition();
inline int getX() const { return m_cx; }
inline int getY() const { return m_cy; }
inline int getZ() const { return m_cz; }
inline bool isLoaded() const { return m_active; }
inline bool isRedrawRequired() const { return m_dirty; }
inline bool isGenerated() const { return m_generated; }
inline bool shouldRender() const { return !m_emptyChunk && m_active && m_generated; }
inline glm::mat4 getModelMatrix() const { return m_model; }
bool isDetailedEnough(Camera* camera);
void draw(Camera* camera, Shader* shader);
void updateFlags();
private:
void formFace(std::vector<Vertex> &vertices, glm::vec3 position, CellFace face);
Planet* m_planet;
class PlanetFace* m_planetFace;
glm::mat4 m_model;
bool m_dirty;
bool m_active;
bool m_generated;
bool m_emptyChunk;
int m_cx, m_cy, m_cz;
GLuint m_vao, m_vbo;
Cell* m_cells[CHUNK_N][CHUNK_N][CHUNK_N];
Cell*** m_cells;
std::vector<Vertex> m_vertices;
};
#endif // __CHUNK_H__

View File

@ -17,18 +17,18 @@ Planet::~Planet()
}
}
void Planet::draw(Camera* camera)
void Planet::draw(Camera* camera, Shader* shader)
{
for (int i = 0; i < 6; i++)
{
m_faces[i]->draw(camera);
}
//for (int i = 0; i < 6; i++)
//{
m_faces[FACE_TOP]->draw(camera, shader);
//}
}
void Planet::tick(GLfloat dtime)
void Planet::tick(Camera* camera, GLfloat dtime)
{
for (int i = 0; i < 6; i++)
{
m_faces[i]->tick(dtime);
}
//for (int i = 0; i < 6; i++)
//{
m_faces[FACE_TOP]->tick(camera, dtime);
//}
}

View File

@ -15,8 +15,11 @@ class Planet
inline void setLightDirection(glm::vec3 lightDir) { m_lightDir = lightDir; }
inline glm::vec3 getLightDirection() const { return m_lightDir; }
void tick(GLfloat dtime);
void draw(Camera* camera);
inline float getRadius() const { return m_radius; }
inline glm::vec3 getPosition() const { return m_position; }
void tick(Camera* camera, GLfloat dtime);
void draw(Camera* camera, Shader* shader);
private:
glm::vec3 m_position;
float m_radius;

View File

@ -2,10 +2,11 @@
#include "planet/Planet.h"
PlanetFace::PlanetFace(Planet* planet, const unsigned int face) :
m_planet(planet), m_face(face)
m_planet(planet), m_face(face), m_pos(glm::vec3(0.0f, 0.0f, 0.0f))
{
// Set face normal depending on face
switch (m_face) {
switch (m_face)
{
case Face::FACE_BOTTOM:
m_normal = glm::vec3(0.0f, -1.0f, 0.0f);
break;
@ -25,42 +26,313 @@ PlanetFace::PlanetFace(Planet* planet, const unsigned int face) :
m_normal = glm::vec3(0.0f, 0.0f, 1.0f);
break;
}
m_chunks = new ChunkManager(this, planet->getRadius());
}
// Create chunks
for(int i=0;i<CHUNKS_W;i++)
PlanetFace::~PlanetFace()
{
}
void PlanetFace::draw(Camera* camera, Shader* shader)
{
if (m_chunks)
{
for(int j=0;j<CHUNKS_H;j++)
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
m_chunks->render(camera, shader);
glDisable(GL_CULL_FACE);
}
}
void PlanetFace::tick(Camera* camera, GLfloat dtime)
{
if (m_chunks)
{
m_chunks->update(camera, dtime);
}
}
// ******** //
// CHUNKS //
// ******** //
ChunkManager::ChunkManager(PlanetFace* face, GLuint chunkCount) : m_face(face)
{
m_forceVisibilityUpdate = true;
for (int x = 0; x < (int)chunkCount; x++)
{
for (int y = 0; y < (int)chunkCount; y++)
{
for(int k=0;k<CHUNKS_D;k++)
for (int z = 0; z < (int)chunkCount; z++)
{
m_chunks[i][j][k] = new Chunk(planet, this, x + i * CHUNK_N, j * CHUNK_N, z + k * CHUNK_N);
m_chunks.push_back(new Chunk(m_face->getPlanet(), m_face, x, y, z));
}
}
}
}
PlanetFace::~PlanetFace()
ChunkManager::~ChunkManager()
{
// Delete chunks
for(int i=0;i<CHUNKS_W;i++)
for(int j=0;j<CHUNKS_H;j++)
for(int k=0;k<CHUNKS_D;k++)
if(m_chunks[i][j][k])
m_chunks[i][j][k]->destroyChunk();
for(auto iterator = m_chunks.begin(); iterator != m_chunks.end(); ++iterator)
{
Chunk* pChunk = (*iterator);
delete pChunk;
}
}
void PlanetFace::draw(Camera* camera)
void ChunkManager::update(Camera* camera, GLfloat dtime)
{
for(int i=0;i<CHUNKS_W;i++)
for(int j=0;j<CHUNKS_H;j++)
for(int k=0;k<CHUNKS_D;k++)
m_chunks[i][j][k]->draw(camera);
updateUnload();
updateLoad();
updateRebuild();
updateGenerate();
updateFlags();
updateVisibility(camera);
updateRender(camera);
}
void PlanetFace::tick(GLfloat dtime)
Chunk* ChunkManager::getChunk(int x, int y, int z)
{
for(int i=0;i<CHUNKS_W;i++)
for(int j=0;j<CHUNKS_H;j++)
for(int k=0;k<CHUNKS_D;k++)
m_chunks[i][j][k]->tick(dtime);
for(auto iterator = m_chunks.begin(); iterator != m_chunks.end(); ++iterator)
{
Chunk* pChunk = (*iterator);
if (pChunk->getX() == x && pChunk->getY() == y && pChunk->getZ() == z)
return pChunk;
}
return NULL;
}
void ChunkManager::updateUnload()
{
// Unload any chunks
for(auto iterator = m_chunkUnloadQueue.begin(); iterator != m_chunkUnloadQueue.end(); ++iterator)
{
Chunk* pChunk = (*iterator);
if(pChunk->isLoaded())
{
pChunk->unload();
m_forceVisibilityUpdate = true;
}
}
// Clear the unload list (every frame)
m_chunkUnloadQueue.clear();
}
void ChunkManager::updateLoad()
{
int lNumOfChunksLoaded = 0;
for(auto iterator = m_chunkLoadQueue.begin(); iterator != m_chunkLoadQueue.end() &&
(lNumOfChunksLoaded != ASYNC_NUM_CHUNKS_PER_FRAME); ++iterator)
{
Chunk* pChunk = (*iterator);
if(pChunk->isLoaded() == false)
{
if(lNumOfChunksLoaded != ASYNC_NUM_CHUNKS_PER_FRAME)
{
pChunk->load();
// Increase the chunks loaded count
lNumOfChunksLoaded++;
m_forceVisibilityUpdate = true;
}
}
}
// Clear the load list (every frame)
m_chunkLoadQueue.clear();
}
void ChunkManager::updateRebuild()
{
// Rebuild any chunks that are in the rebuild chunk list
int lNumRebuiltChunkThisFrame = 0;
for(auto iterator = m_chunkRebuildQueue.begin(); iterator != m_chunkRebuildQueue.end() &&
(lNumRebuiltChunkThisFrame != ASYNC_NUM_CHUNKS_PER_FRAME); ++iterator)
{
Chunk* pChunk = (*iterator);
if(pChunk->isLoaded() && pChunk->isGenerated())
{
if(lNumRebuiltChunkThisFrame != ASYNC_NUM_CHUNKS_PER_FRAME)
{
pChunk->rebuildMesh();
// If we rebuild a chunk, add it to the list of chunks that need their render flags updated
// since we might now be empty or surrounded
m_chunkFlagsQueue.push_back(pChunk);
// Also add our neighbours since they might now be surrounded too (If we have neighbours)
Chunk* pChunkXMinus = getChunk(pChunk->getX()-1, pChunk->getY(), pChunk->getZ());
Chunk* pChunkXPlus = getChunk(pChunk->getX()+1, pChunk->getY(), pChunk->getZ());
Chunk* pChunkYMinus = getChunk(pChunk->getX(), pChunk->getY()-1, pChunk->getZ());
Chunk* pChunkYPlus = getChunk(pChunk->getX(), pChunk->getY()+1, pChunk->getZ());
Chunk* pChunkZMinus = getChunk(pChunk->getX(), pChunk->getY(), pChunk->getZ()-1);
Chunk* pChunkZPlus = getChunk(pChunk->getX(), pChunk->getY(), pChunk->getZ()+1);
if(pChunkXMinus != NULL)
m_chunkFlagsQueue.push_back(pChunkXMinus);
if(pChunkXPlus != NULL)
m_chunkFlagsQueue.push_back(pChunkXPlus);
if(pChunkYMinus != NULL)
m_chunkFlagsQueue.push_back(pChunkYMinus);
if(pChunkYPlus != NULL)
m_chunkFlagsQueue.push_back(pChunkYPlus);
if(pChunkZMinus != NULL)
m_chunkFlagsQueue.push_back(pChunkZMinus);
if(pChunkZPlus != NULL)
m_chunkFlagsQueue.push_back(pChunkZPlus);
// Only rebuild a certain number of chunks per frame
lNumRebuiltChunkThisFrame++;
m_forceVisibilityUpdate = true;
}
}
}
// Clear the rebuild list
m_chunkRebuildQueue.clear();
}
void ChunkManager::updateFlags()
{
for(auto iterator = m_chunkFlagsQueue.begin(); iterator != m_chunkFlagsQueue.end(); ++iterator)
{
Chunk* pChunk = (*iterator);
pChunk->updateFlags();
}
m_chunkFlagsQueue.clear();
}
void ChunkManager::updateGenerate()
{
// Generate any chunks that have not already been generated
for(auto iterator = m_chunkGenerateQueue.begin(); iterator != m_chunkGenerateQueue.end(); ++iterator)
{
Chunk* pChunk = (*iterator);
if(pChunk->isLoaded() && pChunk->isGenerated() == false)
{
pChunk->generate();
if(pChunk->isGenerated())
{
// Only force the visibility update if we actually generate the chunk, some chunks wait in the pre-generate stage...
m_forceVisibilityUpdate = true;
}
}
}
// Clear the generate list (every frame)
m_chunkGenerateQueue.clear();
}
void ChunkManager::updateVisibility(Camera* camera)
{
m_forceVisibilityUpdate = false;
m_chunksVisible.clear();
for(auto iterator = m_chunks.begin(); iterator != m_chunks.end(); ++iterator)
{
Chunk* pChunk = (*iterator);
// TODO: Temporary distance limit
if (glm::abs(glm::length(camera->getPosition() - pChunk->getAbsolutePosition())) > 64.0f)
{
if (pChunk->isLoaded())
{
m_chunkUnloadQueue.push_back(pChunk);
continue;
}
continue;
}
else
{
if (!pChunk->isLoaded())
{
m_chunkLoadQueue.push_back(pChunk);
continue;
}
}
// Generate chunk
if (!pChunk->isGenerated())
{
m_chunkGenerateQueue.push_back(pChunk);
continue;
}
if (pChunk->isRedrawRequired() || !pChunk->isDetailedEnough(camera))
{
m_chunkRebuildQueue.push_back(pChunk);
continue;
}
m_chunksVisible.push_back(pChunk);
}
}
void ChunkManager::updateRender(Camera* camera)
{
// Clear the render list each frame BEFORE we do our tests to see what chunks should be rendered
m_chunkRenderQueue.clear();
for(auto iterator = m_chunksVisible.begin(); iterator != m_chunksVisible.end(); ++iterator)
{
Chunk* pChunk = (*iterator);
if(pChunk != NULL)
{
if(pChunk->isLoaded() && pChunk->isGenerated())
{
if(pChunk->shouldRender()) // Early flags check so we don't always have to do the frustum check...
{
// TODO: frustum culling
//glm::vec3 pos = pChunk->getAbsolutePosition();
//glm::mat4 model = glm::translate(glm::mat4(1.0f), pos);
//camera->updateFrustum(model);
//if(camera->frustumContainsBox(pos, pos + glm::vec3((float)CHUNK_SIZE)))
//{
m_chunkRenderQueue.push_back(pChunk);
//}
}
}
}
}
}
void ChunkManager::render(Camera* camera, Shader* shader)
{
// Render only the chunks that should be rendered
for(auto iterator = m_chunkRenderQueue.begin(); iterator != m_chunkRenderQueue.end(); ++iterator)
{
Chunk* pChunk = (*iterator);
pChunk->draw(camera, shader);
}
}

View File

@ -6,9 +6,7 @@
#include "Shader.h"
#include "Camera.h"
#define CHUNKS_W 1
#define CHUNKS_D CHUNKS_W
#define CHUNKS_H 32
#define ASYNC_NUM_CHUNKS_PER_FRAME 8
enum Face {
FACE_BOTTOM, FACE_TOP,
@ -17,14 +15,57 @@ enum Face {
};
class Planet;
class PlanetFace;
// PlanetFace Chunk Manager
class ChunkManager
{
public:
ChunkManager(PlanetFace* face, GLuint chunkCount);
~ChunkManager();
void update(Camera* camera, GLfloat dtime);
Chunk* getChunk(int x, int y, int z);
void render(Camera* camera, Shader* shader);
private:
void updateUnload();
void updateLoad();
void updateGenerate();
void updateRebuild();
void updateFlags();
void updateVisibility(Camera* camera);
void updateRender(Camera* camera);
std::vector<Chunk*> m_chunks;
std::vector<Chunk*> m_chunksVisible;
// Queues
std::vector<Chunk*> m_chunkUnloadQueue;
std::vector<Chunk*> m_chunkLoadQueue;
std::vector<Chunk*> m_chunkGenerateQueue;
std::vector<Chunk*> m_chunkRebuildQueue;
std::vector<Chunk*> m_chunkRenderQueue;
std::vector<Chunk*> m_chunkFlagsQueue;
PlanetFace* m_face;
int m_chunksLoaded = 0;
bool m_forceVisibilityUpdate;
};
class PlanetFace
{
public:
PlanetFace(Planet* planet, const unsigned int face = Face::FACE_BOTTOM);
~PlanetFace();
void tick(GLfloat dtime);
void draw(Camera* camera);
void tick(Camera* camera, GLfloat dtime);
void draw(Camera* camera, Shader* shader);
inline Planet* getPlanet() const { return m_planet; }
inline const glm::vec3 getPosition() const { return m_planet->getPosition() + m_pos; }
private:
Planet* m_planet;
unsigned int m_face;
@ -32,8 +73,6 @@ class PlanetFace
glm::vec3 m_normal;
glm::vec3 m_pos;
int x, z;
Chunk* m_chunks[CHUNKS_W][CHUNKS_H][CHUNKS_D];
ChunkManager* m_chunks;
};
#endif // __PLANETFACE_H__