diff --git a/CMakeLists.txt b/CMakeLists.txt index 17b0a22..b4183c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(cmake-project-template) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g") set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}) diff --git a/include/camera.hpp b/include/camera.hpp index ce5c591..ab73bfb 100644 --- a/include/camera.hpp +++ b/include/camera.hpp @@ -112,7 +112,7 @@ public: private: - glm::vec3 cameraPos = glm::vec3(0.0, 80.0f, 0.0f); + glm::vec3 cameraPos = glm::vec3(256.0, 80.0f, 256.0f); glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); glm::vec3 direction = glm::vec3(0.0f); diff --git a/include/chunk.hpp b/include/chunk.hpp index bde004e..303fb31 100644 --- a/include/chunk.hpp +++ b/include/chunk.hpp @@ -56,12 +56,8 @@ namespace Chunk std::unique_ptr getBlocksArray(int* len) { return (this->blocks.toArray(len)); } public: - GLuint VAO{0}, VBO{0}, EBO{0}, colorBuffer{0}, vIndex{0}; + GLuint VAO{0}, VBO{0}, EBO{0}, colorBuffer{0}, numVertices{0}; std::atomic unload_timer{0}; - - std::vector vertices; - std::vector colors; - std::vector indices; private: glm::vec3 position{}; diff --git a/include/chunkmanager.hpp b/include/chunkmanager.hpp index 9216d05..5c296fa 100644 --- a/include/chunkmanager.hpp +++ b/include/chunkmanager.hpp @@ -6,6 +6,8 @@ #include +#include + #include "chunk.hpp" #include "globals.hpp" @@ -17,6 +19,7 @@ namespace chunkmanager void stop(); void destroy(); + oneapi::tbb::concurrent_queue& getDeleteVector(); std::array, chunks_volume>& getChunksIndices(); void update(); } diff --git a/include/chunkmesher.hpp b/include/chunkmesher.hpp index 5533568..ff26f4d 100644 --- a/include/chunkmesher.hpp +++ b/include/chunkmesher.hpp @@ -1,22 +1,29 @@ #ifndef CHUNKMESH_H #define CHUNKMESH_H -#include -#include - #include #include +#include +#include +#include + #include "chunk.hpp" #include "globals.hpp" #include "shader.hpp" namespace chunkmesher{ - void mesh(Chunk::Chunk* chunk); - void sendtogpu(Chunk::Chunk* chunk); - void draw(Chunk::Chunk* chunk, glm::mat4 model); + struct MeshData{ + Chunk::Chunk* chunk; + std::vector vertices; + std::vector colors; + std::vector indices; + }; + oneapi::tbb::concurrent_queue& getMeshDataQueue(); - void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight, + void mesh(Chunk::Chunk* chunk); + void sendtogpu(MeshData* mesh_data); + void quad(MeshData* mesh_data, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight, glm::vec3 bottomRight, glm::vec3 normal, Block block, int dim, bool backFace); } diff --git a/include/renderer.hpp b/include/renderer.hpp index 546ea50..f8a7f69 100644 --- a/include/renderer.hpp +++ b/include/renderer.hpp @@ -2,16 +2,21 @@ #define RENDERER_H #include +#include #include "chunk.hpp" +#include "chunkmesher.hpp" #include "shader.hpp" namespace renderer{ + typedef oneapi::tbb::concurrent_unordered_set RenderSet; + void init(); void render(); void destroy(); Shader* getRenderShader(); - oneapi::tbb::concurrent_unordered_set& getChunksToRender(); + RenderSet& getChunksToRender(); + oneapi::tbb::concurrent_queue& getMeshDataQueue(); }; diff --git a/src/chunk.cpp b/src/chunk.cpp index 821b9db..4f98a8d 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -23,10 +23,6 @@ namespace Chunk Chunk ::~Chunk() { - vertices.clear(); - indices.clear(); - colors.clear(); - this->deleteBuffers(); } void Chunk::createBuffers(){ diff --git a/src/chunkgenerator.cpp b/src/chunkgenerator.cpp index 1ebec6b..16d5c4e 100644 --- a/src/chunkgenerator.cpp +++ b/src/chunkgenerator.cpp @@ -14,8 +14,8 @@ #define NOISE_DIRT_MIN 2 #define NOISE_DIRT_X_MULT 0.001f #define NOISE_DIRT_Z_MULT 0.001f -#define NOISE_GRASS_X_MULT 0.035f -#define NOISE_GRASS_Z_MULT 0.035f +#define NOISE_GRASS_X_MULT 0.018f +#define NOISE_GRASS_Z_MULT 0.018f void generatePyramid(Chunk::Chunk *chunk); void generateNoise(Chunk::Chunk *chunk); @@ -56,10 +56,12 @@ void generateNoise(Chunk::Chunk *chunk) int z = HILBERT_XYZ_DECODE[s][2] + CHUNK_SIZE * chunk->getPosition().z; int d2 = HILBERT_XYZ_DECODE[s][0] * CHUNK_SIZE + HILBERT_XYZ_DECODE[s][2]; - if (grassNoiseLUT[d2] == -1) + if (grassNoiseLUT[d2] == -1){ grassNoiseLUT[d2] = GRASS_OFFSET + (int)((0.5 + noiseGen1.eval(x * NOISE_GRASS_X_MULT, z * NOISE_GRASS_Z_MULT) * NOISE_GRASS_MULT)); - if (dirtNoiseLUT[d2] == -1) + } + if (dirtNoiseLUT[d2] == -1){ dirtNoiseLUT[d2] = NOISE_DIRT_MIN + (int)((0.5 + noiseGen2.eval(x * NOISE_DIRT_X_MULT, z * NOISE_DIRT_Z_MULT) * NOISE_DIRT_MULT)); + } int grassNoise = grassNoiseLUT[d2]; int dirtNoise = dirtNoiseLUT[d2]; diff --git a/src/chunkmanager.cpp b/src/chunkmanager.cpp index aa63d6e..01c69d4 100644 --- a/src/chunkmanager.cpp +++ b/src/chunkmanager.cpp @@ -2,10 +2,12 @@ #include #include +#include #include #include #include + #include #include "chunk.hpp" @@ -23,6 +25,8 @@ namespace chunkmanager std::array, chunks_volume> chunks_indices; std::atomic_bool should_run; + + int chunks_volume_real; std::thread init(){ int index{0}; int rr{RENDER_DISTANCE * RENDER_DISTANCE}; @@ -62,27 +66,34 @@ namespace chunkmanager } else b = false; } + chunks_volume_real = index; + + // Also init mesh data queue + for(int i = 0; i < 10; i++) + chunkmesher::getMeshDataQueue().push(new chunkmesher::MeshData()); should_run = true; std::thread update_thread (update); return update_thread; } - std::vector chunks_todelete; + oneapi::tbb::concurrent_queue chunks_todelete; + int nUnloaded{0}; void update(){ while(should_run) { - //cameraPos = theCamera.getPos(); int chunkX=static_cast(theCamera.getAtomicPosX() / CHUNK_SIZE); int chunkY=static_cast(theCamera.getAtomicPosY() / CHUNK_SIZE); int chunkZ=static_cast(theCamera.getAtomicPosZ() / CHUNK_SIZE); // Update other chunks - for(int i = 0; i < chunks_volume; i++) { + for(int i = 0; i < chunks_volume_real; i++) { const uint16_t x = chunks_indices[i][0] + chunkX; const uint16_t y = chunks_indices[i][1] + chunkY; const uint16_t z = chunks_indices[i][2] + chunkZ; const uint32_t index = calculateIndex(x, y, z); + if(x > 1023 || y > 1023 || z > 1023) continue; + ChunkTable::accessor a; if(!chunks.find(a, index)) chunks.emplace(a, std::make_pair(index, new Chunk::Chunk(glm::vec3(x,y,z)))); @@ -101,6 +112,7 @@ namespace chunkmanager return i | (j << 10) | (k << 20); } + oneapi::tbb::concurrent_queue& getDeleteVector(){ return chunks_todelete; } std::array, chunks_volume>& getChunksIndices(){ return chunks_indices; } void stop() { should_run=false; } diff --git a/src/chunkmesher.cpp b/src/chunkmesher.cpp index 061365a..b787d73 100755 --- a/src/chunkmesher.cpp +++ b/src/chunkmesher.cpp @@ -5,13 +5,20 @@ #include "chunk.hpp" #include "chunkmesher.hpp" #include "globals.hpp" +#include "renderer.hpp" #include "spacefilling.hpp" #include "utils.hpp" namespace chunkmesher{ + +oneapi::tbb::concurrent_queue MeshDataQueue; + +oneapi::tbb::concurrent_queue& getMeshDataQueue(){ return MeshDataQueue; } void mesh(Chunk::Chunk* chunk) { + MeshData* mesh_data; + if(!MeshDataQueue.try_pop(mesh_data)) return; /* * Taking inspiration from 0fps and the jme3 porting at @@ -29,14 +36,16 @@ void mesh(Chunk::Chunk* chunk) */ // Cleanup previous data - chunk->vertices.clear(); - chunk->indices.clear(); - chunk->colors.clear(); - chunk->vIndex = 0; + chunk->numVertices = 0; + mesh_data->chunk = chunk; + mesh_data->vertices.clear(); + mesh_data->indices.clear(); + mesh_data->colors.clear(); // Abort if chunk is empty if(chunk->getState(Chunk::CHUNK_STATE_EMPTY)){ chunk->setState(Chunk::CHUNK_STATE_MESHED, true); + renderer::getMeshDataQueue().push(mesh_data); return; } @@ -45,6 +54,7 @@ void mesh(Chunk::Chunk* chunk) std::unique_ptr blocks = chunk->getBlocksArray(&length); if(length == 0) { chunk->setState(Chunk::CHUNK_STATE_MESHED, true); + renderer::getMeshDataQueue().push(mesh_data); return; } @@ -150,7 +160,7 @@ void mesh(Chunk::Chunk* chunk) dv[2] = 0; dv[v] = h; - quad(chunk, glm::vec3(x[0], x[1], x[2]), + quad(mesh_data, glm::vec3(x[0], x[1], x[2]), glm::vec3(x[0] + du[0], x[1] + du[1], x[2] + du[2]), glm::vec3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]), @@ -186,17 +196,21 @@ void mesh(Chunk::Chunk* chunk) } chunk->setState(Chunk::CHUNK_STATE_MESHED, true); + renderer::getMeshDataQueue().push(mesh_data); + return; } -void sendtogpu(Chunk::Chunk* chunk) +void sendtogpu(MeshData* mesh_data) { - if (chunk->vIndex > 0) + if (mesh_data->chunk->numVertices > 0) { - // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). - glBindVertexArray(chunk->VAO); + if(mesh_data->chunk->VAO == 0) mesh_data->chunk->createBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, chunk->VBO); - glBufferData(GL_ARRAY_BUFFER, chunk->vertices.size() * sizeof(GLfloat), &(chunk->vertices[0]), GL_STATIC_DRAW); + // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). + glBindVertexArray(mesh_data->chunk->VAO); + + glBindBuffer(GL_ARRAY_BUFFER, mesh_data->chunk->VBO); + glBufferData(GL_ARRAY_BUFFER, mesh_data->vertices.size() * sizeof(GLfloat), &(mesh_data->vertices[0]), GL_STATIC_DRAW); // position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0); @@ -207,12 +221,12 @@ void sendtogpu(Chunk::Chunk* chunk) sizeof(float))); glEnableVertexAttribArray(1); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, chunk->EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, chunk->indices.size() * sizeof(GLuint), &(chunk->indices[0]), GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh_data->chunk->EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh_data->indices.size() * sizeof(GLuint), &(mesh_data->indices[0]), GL_STATIC_DRAW); // texcoords attribute - glBindBuffer(GL_ARRAY_BUFFER, chunk->colorBuffer); - glBufferData(GL_ARRAY_BUFFER, chunk->colors.size() * sizeof(GLfloat), &(chunk->colors[0]), GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, mesh_data->chunk->colorBuffer); + glBufferData(GL_ARRAY_BUFFER, mesh_data->colors.size() * sizeof(GLfloat), &(mesh_data->colors[0]), GL_STATIC_DRAW); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0); @@ -220,119 +234,118 @@ void sendtogpu(Chunk::Chunk* chunk) glBindVertexArray(0); // save the number of indices of the mesh, it is needed later for drawing - chunk->vIndex = (GLuint)(chunk->indices.size()); + mesh_data->chunk->numVertices = (GLuint)(mesh_data->indices.size()); // once data has been sent to the GPU, it can be cleared from system RAM - chunk->vertices.clear(); - chunk->indices.clear(); - chunk->colors.clear(); + mesh_data->vertices.clear(); + mesh_data->indices.clear(); + mesh_data->colors.clear(); } // mark the chunk mesh has loaded on GPU - chunk->setState(Chunk::CHUNK_STATE_MESH_LOADED, true); + mesh_data->chunk->setState(Chunk::CHUNK_STATE_MESH_LOADED, true); } -void quad(Chunk::Chunk* chunk, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight, +void quad(MeshData* mesh_data, glm::vec3 bottomLeft, glm::vec3 topLeft, glm::vec3 topRight, glm::vec3 bottomRight, glm::vec3 normal, Block block, int dim, bool backFace) { + mesh_data->vertices.push_back(bottomLeft.x); + mesh_data->vertices.push_back(bottomLeft.y); + mesh_data->vertices.push_back(bottomLeft.z); + mesh_data->vertices.push_back(normal.x); + mesh_data->vertices.push_back(normal.y); + mesh_data->vertices.push_back(normal.z); - chunk->vertices.push_back(bottomLeft.x); - chunk->vertices.push_back(bottomLeft.y); - chunk->vertices.push_back(bottomLeft.z); - chunk->vertices.push_back(normal.x); - chunk->vertices.push_back(normal.y); - chunk->vertices.push_back(normal.z); + mesh_data->vertices.push_back(bottomRight.x); + mesh_data->vertices.push_back(bottomRight.y); + mesh_data->vertices.push_back(bottomRight.z); + mesh_data->vertices.push_back(normal.x); + mesh_data->vertices.push_back(normal.y); + mesh_data->vertices.push_back(normal.z); - chunk->vertices.push_back(bottomRight.x); - chunk->vertices.push_back(bottomRight.y); - chunk->vertices.push_back(bottomRight.z); - chunk->vertices.push_back(normal.x); - chunk->vertices.push_back(normal.y); - chunk->vertices.push_back(normal.z); + mesh_data->vertices.push_back(topLeft.x); + mesh_data->vertices.push_back(topLeft.y); + mesh_data->vertices.push_back(topLeft.z); + mesh_data->vertices.push_back(normal.x); + mesh_data->vertices.push_back(normal.y); + mesh_data->vertices.push_back(normal.z); - chunk->vertices.push_back(topLeft.x); - chunk->vertices.push_back(topLeft.y); - chunk->vertices.push_back(topLeft.z); - chunk->vertices.push_back(normal.x); - chunk->vertices.push_back(normal.y); - chunk->vertices.push_back(normal.z); - - chunk->vertices.push_back(topRight.x); - chunk->vertices.push_back(topRight.y); - chunk->vertices.push_back(topRight.z); - chunk->vertices.push_back(normal.x); - chunk->vertices.push_back(normal.y); - chunk->vertices.push_back(normal.z); + mesh_data->vertices.push_back(topRight.x); + mesh_data->vertices.push_back(topRight.y); + mesh_data->vertices.push_back(topRight.z); + mesh_data->vertices.push_back(normal.x); + mesh_data->vertices.push_back(normal.y); + mesh_data->vertices.push_back(normal.z); // texcoords if(dim == 0){ - chunk->colors.push_back(0); - chunk->colors.push_back(0); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(0); + mesh_data->colors.push_back(0); + mesh_data->colors.push_back(((int)block) - 2); - chunk->colors.push_back(abs(bottomRight.z - bottomLeft.z)); - chunk->colors.push_back(abs(bottomRight.y - bottomLeft.y)); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(abs(bottomRight.z - bottomLeft.z)); + mesh_data->colors.push_back(abs(bottomRight.y - bottomLeft.y)); + mesh_data->colors.push_back(((int)block) - 2); - chunk->colors.push_back(abs(topLeft.z - bottomLeft.z)); - chunk->colors.push_back(abs(topLeft.y - bottomLeft.y)); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(abs(topLeft.z - bottomLeft.z)); + mesh_data->colors.push_back(abs(topLeft.y - bottomLeft.y)); + mesh_data->colors.push_back(((int)block) - 2); - chunk->colors.push_back(abs(topRight.z - bottomLeft.z)); - chunk->colors.push_back(abs(topRight.y - bottomLeft.y)); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(abs(topRight.z - bottomLeft.z)); + mesh_data->colors.push_back(abs(topRight.y - bottomLeft.y)); + mesh_data->colors.push_back(((int)block) - 2); }else if(dim == 1){ - chunk->colors.push_back(0); - chunk->colors.push_back(0); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(0); + mesh_data->colors.push_back(0); + mesh_data->colors.push_back(((int)block) - 2); - chunk->colors.push_back(abs(bottomRight.z - bottomLeft.z)); - chunk->colors.push_back(abs(bottomRight.x - bottomLeft.x)); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(abs(bottomRight.z - bottomLeft.z)); + mesh_data->colors.push_back(abs(bottomRight.x - bottomLeft.x)); + mesh_data->colors.push_back(((int)block) - 2); - chunk->colors.push_back(abs(topLeft.z - bottomLeft.z)); - chunk->colors.push_back(abs(topLeft.x - bottomLeft.x)); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(abs(topLeft.z - bottomLeft.z)); + mesh_data->colors.push_back(abs(topLeft.x - bottomLeft.x)); + mesh_data->colors.push_back(((int)block) - 2); - chunk->colors.push_back(abs(topRight.z - bottomLeft.z)); - chunk->colors.push_back(abs(topRight.x - bottomLeft.x)); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(abs(topRight.z - bottomLeft.z)); + mesh_data->colors.push_back(abs(topRight.x - bottomLeft.x)); + mesh_data->colors.push_back(((int)block) - 2); }else{ - chunk->colors.push_back(0); - chunk->colors.push_back(0); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(0); + mesh_data->colors.push_back(0); + mesh_data->colors.push_back(((int)block) - 2); - chunk->colors.push_back(abs(bottomRight.x - bottomLeft.x)); - chunk->colors.push_back(abs(bottomRight.y - bottomLeft.y)); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(abs(bottomRight.x - bottomLeft.x)); + mesh_data->colors.push_back(abs(bottomRight.y - bottomLeft.y)); + mesh_data->colors.push_back(((int)block) - 2); - chunk->colors.push_back(abs(topLeft.x - bottomLeft.x)); - chunk->colors.push_back(abs(topLeft.y - bottomLeft.y)); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(abs(topLeft.x - bottomLeft.x)); + mesh_data->colors.push_back(abs(topLeft.y - bottomLeft.y)); + mesh_data->colors.push_back(((int)block) - 2); - chunk->colors.push_back(abs(topRight.x - bottomLeft.x)); - chunk->colors.push_back(abs(topRight.y - bottomLeft.y)); - chunk->colors.push_back(((int)block) - 2); + mesh_data->colors.push_back(abs(topRight.x - bottomLeft.x)); + mesh_data->colors.push_back(abs(topRight.y - bottomLeft.y)); + mesh_data->colors.push_back(((int)block) - 2); } if (backFace) { - chunk->indices.push_back(chunk->vIndex + 2); - chunk->indices.push_back(chunk->vIndex); - chunk->indices.push_back(chunk->vIndex + 1); - chunk->indices.push_back(chunk->vIndex + 1); - chunk->indices.push_back(chunk->vIndex + 3); - chunk->indices.push_back(chunk->vIndex + 2); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 2); + mesh_data->indices.push_back(mesh_data->chunk->numVertices); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 1); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 1); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 3); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 2); } else { - chunk->indices.push_back(chunk->vIndex + 2); - chunk->indices.push_back(chunk->vIndex + 3); - chunk->indices.push_back(chunk->vIndex + 1); - chunk->indices.push_back(chunk->vIndex + 1); - chunk->indices.push_back(chunk->vIndex); - chunk->indices.push_back(chunk->vIndex + 2); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 2); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 3); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 1); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 1); + mesh_data->indices.push_back(mesh_data->chunk->numVertices); + mesh_data->indices.push_back(mesh_data->chunk->numVertices + 2); } - chunk->vIndex += 4; + mesh_data->chunk->numVertices += 4; } }; diff --git a/src/renderer.cpp b/src/renderer.cpp index 8214eb0..a02899a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1,19 +1,24 @@ #include "renderer.hpp" +#include +#include + #include "chunkmanager.hpp" #include "chunkmesher.hpp" #include "globals.hpp" #include "stb_image.h" namespace renderer{ - oneapi::tbb::concurrent_unordered_set chunks_torender; - oneapi::tbb::concurrent_unordered_set render_todelete; + RenderSet chunks_torender; + oneapi::tbb::concurrent_vector render_todelete; + oneapi::tbb::concurrent_queue MeshDataQueue; Shader* theShader; GLuint chunkTexture; Shader* getRenderShader() { return theShader; } - oneapi::tbb::concurrent_unordered_set& getChunksToRender(){ return chunks_torender; } + RenderSet& getChunksToRender(){ return chunks_torender; } + oneapi::tbb::concurrent_queue& getMeshDataQueue(){ return MeshDataQueue; } void init(){ @@ -50,18 +55,45 @@ namespace renderer{ theShader->use(); theShader->setVec3("viewPos", cameraPos); - for(Chunk::Chunk* c : chunks_torender){ + for(auto& n : render_todelete){ + // we can get away with unsafe erase as access to the container is only done by this + // thread + n->deleteBuffers(); + chunks_torender.unsafe_erase(n); + } + render_todelete.clear(); + + chunkmesher::MeshData* m; + while(MeshDataQueue.try_pop(m)){ + chunkmesher::sendtogpu(m); + chunkmesher::getMeshDataQueue().push(m); + } + + for(auto& c : chunks_torender){ if(! (c->getState(Chunk::CHUNK_STATE_MESHED))) continue; + + float dist = glm::distance(c->getPosition(), cameraChunkPos); + if(dist >= static_cast(RENDER_DISTANCE)*1.75f){ + // When the chunk is outside render distance - // If the mesh is ready send it to the gpu - if(! (c->getState(Chunk::CHUNK_STATE_MESH_LOADED))){ - if(c->VAO == 0) c->createBuffers(); - chunkmesher::sendtogpu(c); - c->setState(Chunk::CHUNK_STATE_MESH_LOADED, true); - } + if(c->getState(Chunk::CHUNK_STATE_OUTOFVISION)){ + if(glfwGetTime() - c->unload_timer > UNLOAD_TIMEOUT){ + // If chunk was already out and enough time has passed + // Mark the chunk to be unloaded + // And mark is to be removed from the render set + render_todelete.push_back(c); + chunkmanager::getDeleteVector().push(c); + } + } else{ + // Mark has out of vision and annotate when it started + c->setState(Chunk::CHUNK_STATE_OUTOFVISION, true); + c->setState(Chunk::CHUNK_STATE_UNLOADED, false); + c->unload_timer = glfwGetTime(); + } + + }else if(dist <= static_cast(RENDER_DISTANCE)){ + if(!c->getState(Chunk::CHUNK_STATE_MESH_LOADED)) continue; - if(glm::distance(c->getPosition(), cameraChunkPos) < static_cast(RENDER_DISTANCE)){ - // if chunk can be seen // reset out-of-vision and unload flags c->setState(Chunk::CHUNK_STATE_OUTOFVISION, false); c->setState(Chunk::CHUNK_STATE_UNLOADED, false); @@ -89,7 +121,7 @@ namespace renderer{ if (!out) { - if(c->vIndex > 0) + if(c->numVertices > 0) { // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // wireframe mode theShader->setMat4("model", model); @@ -97,36 +129,14 @@ namespace renderer{ theShader->setMat4("projection", theCamera.getProjection()); glBindVertexArray(c->VAO); - glDrawElements(GL_TRIANGLES, c->vIndex , GL_UNSIGNED_INT, 0); + glDrawElements(GL_TRIANGLES, c->numVertices , GL_UNSIGNED_INT, 0); glBindVertexArray(0); } } - - }else{ - // When the chunk is outside render distance - - if(c->getState(Chunk::CHUNK_STATE_OUTOFVISION) && glfwGetTime() - - c->unload_timer > UNLOAD_TIMEOUT){ - // If chunk was already out and enough time has passed - // Mark the chunk to be unloaded - c->setState(Chunk::CHUNK_STATE_UNLOADED, true); - // And delete it from the render set - render_todelete.insert(c); - } else{ - // Mark has out of vision and annotate when it started - c->setState(Chunk::CHUNK_STATE_OUTOFVISION, true); - c->setState(Chunk::CHUNK_STATE_UNLOADED, false); - c->unload_timer = glfwGetTime(); - } - } } - - for(Chunk::Chunk* i : render_todelete){ - chunks_torender.unsafe_erase(i); - } - render_todelete.clear(); } + void destroy(){ delete theShader; }