diff options
author | Tyler Murphy <tylermurphy534@gmail.com> | 2022-09-27 17:03:43 -0400 |
---|---|---|
committer | Tyler Murphy <tylermurphy534@gmail.com> | 2022-09-27 17:03:43 -0400 |
commit | 9b60b862e58905780bf47f69a34522fde046ebea (patch) | |
tree | bda8f9c998cdeec6ad1a5b4fb6e60800dbaca8ad /src | |
parent | async chunk meshing (diff) | |
download | minecraftvulkan-9b60b862e58905780bf47f69a34522fde046ebea.tar.gz minecraftvulkan-9b60b862e58905780bf47f69a34522fde046ebea.tar.bz2 minecraftvulkan-9b60b862e58905780bf47f69a34522fde046ebea.zip |
procedural chunk loading
Diffstat (limited to '')
-rw-r--r-- | src/chunk.cpp | 24 | ||||
-rw-r--r-- | src/chunk.hpp | 1 | ||||
-rwxr-xr-x | src/first_app.cpp | 64 | ||||
-rwxr-xr-x | src/first_app.hpp | 11 | ||||
-rw-r--r-- | src/simple_renderer.cpp | 4 |
5 files changed, 77 insertions, 27 deletions
diff --git a/src/chunk.cpp b/src/chunk.cpp index f9ddb54..e830c57 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -16,14 +16,14 @@ Chunk::Chunk(int32_t gridX, int32_t gridZ, uint32_t world_seed) } Chunk::~Chunk() { - if(chunkMesh != nullptr) - delete chunkMesh; if(worker.joinable()) worker.join(); + if(chunkMesh != nullptr) + delete chunkMesh; } // -// CHUNK CREATION AND DELETION +// CHUNK CREATION, DELETION, AND RETREVAL // static std::map<std::pair<int32_t, int32_t>, Chunk*> chunks{}; @@ -38,10 +38,17 @@ Chunk* Chunk::getChunk(int32_t gridX, int32_t gridZ) { if(chunks.count({gridX, gridZ})) { return chunks[{gridX, gridZ}]; } else { - return NULL; + return nullptr; } } +void Chunk::deleteChunk(int32_t gridX, int32_t gridZ) { + Chunk* chunk = getChunk(gridX, gridZ); + if(chunk == nullptr) return; // Chunk does not exist or is already deleted + delete chunk; + chunks.erase({gridX, gridZ}); +} + // // CHUNK TEXTURE AND BLOCK LOADING // @@ -51,7 +58,7 @@ static std::map<std::string, uint32_t> texturesIds{}; static std::vector<xe::Image*> textures{}; void loadTexture(const std::string& filePath) { - xe::Image* image = xe::Engine::getInstance()->loadImageFromFile(filePath, false); + xe::Image* image = new xe::Image(filePath, false); texturesIds[filePath] = static_cast<uint32_t>(textures.size()); textures.push_back(image); } @@ -88,12 +95,15 @@ void Chunk::unload() { // void Chunk::createMeshAsync(Chunk* c) { + if(c == nullptr) return; if(c->working) return; + if(c->worker.joinable()) + c->worker.join(); c->worker = std::thread(createMesh, c); } void Chunk::createMesh(Chunk* c) { - c->working = true; + if(c == nullptr) return; c->vertexData.data.clear(); for(int32_t x=0;x<16;x++) { for(int32_t y=0; y<256; y++) { @@ -152,7 +162,7 @@ xe::Model* Chunk::getMesh() { xe::Model::Builder builder{}; builder.vertexData = vertexData; builder.vertexSize = 36; - chunkMesh = new xe::Model(xe::Engine::getInstance()->getDevice(), builder); + chunkMesh = new xe::Model(builder); reloadRequired = false; } return chunkMesh; diff --git a/src/chunk.hpp b/src/chunk.hpp index c506ca0..c53a0d3 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -39,6 +39,7 @@ class Chunk { static Chunk* newChunk(int32_t gridX, int32_t gridZ, uint32_t world_seed); static Chunk* getChunk(int32_t gridX, int32_t gridZ); + static void deleteChunk(int32_t gridX, int32_t gridZ); static void createMesh(Chunk* c); static void createMeshAsync(Chunk* c); diff --git a/src/first_app.cpp b/src/first_app.cpp index 08f6f0c..43047f7 100755 --- a/src/first_app.cpp +++ b/src/first_app.cpp @@ -1,5 +1,4 @@ #include "first_app.hpp" -#include "chunk.hpp" namespace app { @@ -11,15 +10,11 @@ void FirstApp::run() { Chunk::load(); - for(int32_t x = 0; x < 10; x++) { - for(int32_t z = 0; z < 10; z++) { - Chunk* chunk = Chunk::newChunk(x, z, 53463); - Chunk::createMeshAsync(chunk); - auto chunkObject = xe::GameObject::createGameObject(); - chunkObject.transform.translation = {16.f*x, 0.f, 16.f*z}; - gameObjects.push_back(std::move(chunkObject)); - } - } + auto viewerObject = xe::GameObject::createGameObject(); + viewerObject.transform.translation = {0.f, 10.f, 0.f}; + viewerObject.transform.rotation.y = glm::radians(45.f); + + createGameObjects(viewerObject); SimpleRenderer renderer{xeEngine, Chunk::getTextures()}; @@ -27,9 +22,6 @@ void FirstApp::run() { sound.setLooping(true); sound.play(); - auto viewerObject = xe::GameObject::createGameObject(); - viewerObject.transform.translation = {0.f, 10.f, 0.f}; - viewerObject.transform.rotation.y = glm::radians(45.f); KeyboardMovementController cameraController{xeEngine.getInput(), viewerObject}; while (xeEngine.poll()) { @@ -40,10 +32,12 @@ void FirstApp::run() { xeEngine.getCamera().setViewYXZ(viewerObject.transform.translation, viewerObject.transform.rotation); if(xeEngine.beginFrame()) { - renderer.render(gameObjects, xeEngine.getCamera()); + renderer.render(loadedChunks, xeEngine.getCamera()); xeEngine.endFrame(); } + reloadLoadedChunks(viewerObject); + } xeEngine.close(); @@ -52,4 +46,46 @@ void FirstApp::run() { } +void FirstApp::createGameObjects(xe::GameObject& viewer) { + int width = 2*RENDER_DISTANCE+1; + loadedChunks.clear(); + for(int32_t x = 0; x < width; x++) { + for(int32_t z = 0; z < width; z++) { + auto gameObject = xe::GameObject::createGameObject(); + gameObject.transform.translation = glm::vec3(0.f); + loadedChunks.push_back(std::move(gameObject)); + } + } +} + +void FirstApp::reloadLoadedChunks(xe::GameObject& viewer) { + viewX = static_cast<int>(floor(viewer.transform.translation.x / 16.f)); + viewZ = static_cast<int>(floor(viewer.transform.translation.z / 16.f)); + int width = 2*RENDER_DISTANCE+1; + int minX = viewX - RENDER_DISTANCE; + int minZ = viewZ - RENDER_DISTANCE; + int maxX = viewX + RENDER_DISTANCE; + int maxZ = viewZ + RENDER_DISTANCE; + for(int32_t x = 0; x < width; x++) { + for(int32_t z = 0; z < width; z++) { + auto& gameObject = loadedChunks[x + z * width]; + int gridX = static_cast<int>(floor(gameObject.transform.translation.x / 16.f)); + int gridZ = static_cast<int>(floor(gameObject.transform.translation.z / 16.f)); + int newGridX = minX + x; + int newGridZ = minZ + z; + if(gridX < minX || gridZ < minZ || gridX > maxX || gridZ > maxZ) + Chunk::deleteChunk(gridX, gridZ); + Chunk* chunk = Chunk::getChunk(newGridX, newGridZ); + if(chunk == nullptr) { + chunk = Chunk::newChunk(newGridX, newGridZ, 12345); + Chunk::createMeshAsync(chunk); + Chunk::createMeshAsync(Chunk::getChunk(newGridX-1, newGridZ)); + Chunk::createMeshAsync(Chunk::getChunk(newGridX, newGridZ+1)); + } + gameObject.model = chunk->getMesh(); + gameObject.transform.translation = glm::vec3(newGridX * 16.f, 0, newGridZ * 16.f); + } + } +} + }
\ No newline at end of file diff --git a/src/first_app.hpp b/src/first_app.hpp index 3339b04..d361296 100755 --- a/src/first_app.hpp +++ b/src/first_app.hpp @@ -4,6 +4,7 @@ #include "keyboard_movement_controller.hpp" #include "simple_renderer.hpp" +#include "chunk.hpp" #define GLM_FORCE_RADIANS #define GLM_FORCE_DEPTH_ZERO_TO_ONE @@ -31,9 +32,15 @@ class FirstApp { static constexpr int WIDTH = 800; static constexpr int HEIGHT = 600; + static constexpr int RENDER_DISTANCE = 10; - xe::Engine xeEngine; + void createGameObjects(xe::GameObject& viewer); + void reloadLoadedChunks(xe::GameObject& viewer); + + + int viewX, viewZ; - std::vector<xe::GameObject> gameObjects; + xe::Engine xeEngine; + std::vector<xe::GameObject> loadedChunks; }; }
\ No newline at end of file diff --git a/src/simple_renderer.cpp b/src/simple_renderer.cpp index 22046be..d13e7ac 100644 --- a/src/simple_renderer.cpp +++ b/src/simple_renderer.cpp @@ -29,10 +29,6 @@ void SimpleRenderer::render(std::vector<xe::GameObject> &gameObjects, xe::Camera PushConstant pc{}; pc.modelMatrix = obj.transform.mat4(); pc.normalMatrix = obj.transform.normalMatrix(); - - Chunk* chunk = Chunk::getChunk(obj.transform.translation.x/16.f, obj.transform.translation.z/16.f); - obj.model = chunk->getMesh(); - xeRenderSystem->loadPushConstant(&pc); xeRenderSystem->render(obj); } |