diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/chunk.cpp | 191 | ||||
-rw-r--r-- | src/chunk.hpp | 23 | ||||
-rwxr-xr-x | src/first_app.cpp | 32 | ||||
-rwxr-xr-x | src/first_app.hpp | 2 | ||||
-rw-r--r-- | src/simple_renderer.cpp | 7 |
5 files changed, 139 insertions, 116 deletions
diff --git a/src/chunk.cpp b/src/chunk.cpp index 1c15fa7..f9ddb54 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -1,16 +1,33 @@ #include "chunk.hpp" + namespace app { -static std::map<std::pair<int32_t, int32_t>, Chunk*> chunks{}; +// +// CHUNK CONSTRUCTORS AND DECONSTUCTORS +// Chunk::Chunk(int32_t gridX, int32_t gridZ, uint32_t world_seed) : world_seed{world_seed}, chunk_seed{(world_seed * gridX) + (world_seed * gridZ) / 2}, gridX{gridX}, gridZ{gridZ} { + chunkMesh = nullptr; generate(); } +Chunk::~Chunk() { + if(chunkMesh != nullptr) + delete chunkMesh; + if(worker.joinable()) + worker.join(); +} + +// +// CHUNK CREATION AND DELETION +// + +static std::map<std::pair<int32_t, int32_t>, Chunk*> chunks{}; + Chunk* Chunk::newChunk(int32_t gridX, int32_t gridZ, uint32_t world_seed) { Chunk* chunk = new Chunk(gridX, gridZ, world_seed); chunks[{gridX, gridZ}] = std::move(chunk); @@ -25,36 +42,9 @@ Chunk* Chunk::getChunk(int32_t gridX, int32_t gridZ) { } } -uint8_t Chunk::getBlock(int32_t x, int32_t y, int32_t z) { - if(y > 256) return AIR; - if(y < 0) return INVALID; - int chunkX = gridX; - int chunkZ = gridZ; - if(x < 0) { - chunkX--; - } else if(x > 15) { - chunkX++; - } - if(z < 0) { - chunkZ--; - } else if(z > 15) { - chunkZ++; - } - x = (x+16)%16; - z = (z+16)%16; - if(chunkX == gridX && chunkZ == gridZ) { - int index = x + (z * 16) + (y * 256); - return cubes[index]; - } else { - Chunk* chunk = getChunk(chunkX, chunkZ); - if(chunk == NULL) { - return INVALID; - } else { - int index = x + (z * 16) + (y * 256); - return chunk->cubes[index]; - } - } -} +// +// CHUNK TEXTURE AND BLOCK LOADING +// static std::map<uint8_t, Block> blocks{}; static std::map<std::string, uint32_t> texturesIds{}; @@ -93,74 +83,121 @@ void Chunk::unload() { textures.clear(); } -void Chunk::setBlock(int32_t x, int32_t y, int32_t z, uint8_t block) { - int index = x + (z * 16) + (y * 256); - cubes[index] = block; -} +// +// CHUNK MESH CREATION FOR BOTH SYNC AND ASYNC +// -std::shared_ptr<xe::Model> Chunk::getMesh() { - if(reloadRequired) { - delete chunkMesh.get(); - xe::Model::Builder builder{}; - builder.vertexData = vertexData; - builder.vertexSize = 36; - chunkMesh = std::make_shared<xe::Model>(xe::Engine::getInstance()->getDevice(), builder); - } - return chunkMesh; +void Chunk::createMeshAsync(Chunk* c) { + if(c->working) return; + c->worker = std::thread(createMesh, c); } -void Chunk::createMeshAsync() { - if(working) return; - // worker = std::thread(createMesh); -} - -void Chunk::createMesh() { - working = true; - vertexData.data.clear(); +void Chunk::createMesh(Chunk* c) { + c->working = true; + c->vertexData.data.clear(); for(int32_t x=0;x<16;x++) { for(int32_t y=0; y<256; y++) { for(int32_t z=0; z<16; z++) { - uint8_t block = getBlock(x,y,z); + uint8_t block = c->getBlock(x,y,z); if(block == AIR) continue; - if(getBlock(x+1,y,z) == AIR) { - addVerticies(0, x, y, z, block); + if(c->getBlock(x+1,y,z) == AIR) { + c->addVerticies(c, 0, x, y, z, block); } - if(getBlock(x-1,y,z) == AIR) { - addVerticies(1, x, y, z, block); + if(c->getBlock(x-1,y,z) == AIR) { + c->addVerticies(c, 1, x, y, z, block); } - if(getBlock(x,y+1,z) == AIR) { - addVerticies(2, x, y, z, block); + if(c->getBlock(x,y+1,z) == AIR) { + c->addVerticies(c, 2, x, y, z, block); } - if(getBlock(x,y-1,z) == AIR) { - addVerticies(3, x, y, z, block); + if(c->getBlock(x,y-1,z) == AIR) { + c->addVerticies(c, 3, x, y, z, block); } - if(getBlock(x,y,z+1) == AIR) { - addVerticies(4, x, y, z, block); + if(c->getBlock(x,y,z+1) == AIR) { + c->addVerticies(c, 4, x, y, z, block); } - if(getBlock(x,y,z-1) == AIR) { - addVerticies(5, x, y, z, block); + if(c->getBlock(x,y,z-1) == AIR) { + c->addVerticies(c, 5, x, y, z, block); } } } } - working = false; - reloadRequired = true; + c->working = false; + c->reloadRequired = true; } -void Chunk::addVerticies(uint8_t side, int32_t x, int32_t y, int32_t z, uint8_t block) { +void Chunk::addVerticies(Chunk* c, uint8_t side, int32_t x, int32_t y, int32_t z, uint8_t block) { for(int i = 0; i < 6; i ++) { - vertexData.write<float>(px[side * 6 + i][0] + x); - vertexData.write<float>(px[side * 6 + i][1] + y); - vertexData.write<float>(px[side * 6 + i][2] + z); - vertexData.write<float>(nm[side][0]); - vertexData.write<float>(nm[side][1]); - vertexData.write<float>(nm[side][2]); - vertexData.write<float>(uv[i][0]); - vertexData.write<float>(uv[i][1]); - vertexData.write<uint32_t>(static_cast<uint32_t>(blocks[block].textures[side])); + c->vertexData.write<float>(px[side * 6 + i][0] + x); + c->vertexData.write<float>(px[side * 6 + i][1] + y); + c->vertexData.write<float>(px[side * 6 + i][2] + z); + c->vertexData.write<float>(nm[side][0]); + c->vertexData.write<float>(nm[side][1]); + c->vertexData.write<float>(nm[side][2]); + c->vertexData.write<float>(uv[i][0]); + c->vertexData.write<float>(uv[i][1]); + c->vertexData.write<uint32_t>(static_cast<uint32_t>(blocks[block].textures[side])); + } +} + +// +// CHUNK GETTERS AND SETTORS +// + +xe::Model* Chunk::getMesh() { + if(reloadRequired) { + if(chunkMesh != nullptr) + delete chunkMesh; + if(worker.joinable()) + worker.join(); + xe::Model::Builder builder{}; + builder.vertexData = vertexData; + builder.vertexSize = 36; + chunkMesh = new xe::Model(xe::Engine::getInstance()->getDevice(), builder); + reloadRequired = false; } + return chunkMesh; } +uint8_t Chunk::getBlock(int32_t x, int32_t y, int32_t z) { + if(y > 256) return AIR; + if(y < 0) return INVALID; + int chunkX = gridX; + int chunkZ = gridZ; + if(x < 0) { + chunkX--; + } else if(x > 15) { + chunkX++; + } + if(z < 0) { + chunkZ--; + } else if(z > 15) { + chunkZ++; + } + x = (x+16)%16; + z = (z+16)%16; + if(chunkX == gridX && chunkZ == gridZ) { + int index = x + (z * 16) + (y * 256); + return cubes[index]; + } else { + Chunk* chunk = getChunk(chunkX, chunkZ); + if(chunk == NULL) { + return INVALID; + } else { + int index = x + (z * 16) + (y * 256); + return chunk->cubes[index]; + } + } +} + +void Chunk::setBlock(int32_t x, int32_t y, int32_t z, uint8_t block) { + int index = x + (z * 16) + (y * 256); + cubes[index] = block; +} + +// +// CHUNK GENERATION +// + void Chunk::generate() { cubes.resize(16*16*256); diff --git a/src/chunk.hpp b/src/chunk.hpp index e2cfab5..c506ca0 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -38,31 +38,30 @@ class Chunk { static std::vector<xe::Image*>& getTextures(); static Chunk* newChunk(int32_t gridX, int32_t gridZ, uint32_t world_seed); + static Chunk* getChunk(int32_t gridX, int32_t gridZ); - Chunk(int32_t gridX, int32_t gridZ, uint32_t world_seed); - ~Chunk() {}; - - const int32_t gridX, gridZ; - const uint32_t world_seed, chunk_seed; - - void createMesh(); - void createMeshAsync(); - std::shared_ptr<xe::Model> getMesh(); + static void createMesh(Chunk* c); + static void createMeshAsync(Chunk* c); + xe::Model* getMesh(); uint8_t getBlock(int32_t x, int32_t y, int32_t z); void setBlock(int32_t x, int32_t y, int32_t z, uint8_t block); - static Chunk* getChunk(int32_t x, int32_t z); + const int32_t gridX, gridZ; + const uint32_t world_seed, chunk_seed; private: + Chunk(int32_t gridX, int32_t gridZ, uint32_t world_seed); + ~Chunk(); + void generate(); - void addVerticies(uint8_t side, int32_t x, int32_t y, int32_t z, uint8_t block); + static void addVerticies(Chunk* c, uint8_t side, int32_t x, int32_t y, int32_t z, uint8_t block); bool reloadRequired{false}; bool working{false}; - std::shared_ptr<xe::Model> chunkMesh; + xe::Model* chunkMesh; xe::Model::Data vertexData; std::vector<uint8_t> cubes; std::thread worker; diff --git a/src/first_app.cpp b/src/first_app.cpp index 968f7f8..08f6f0c 100755 --- a/src/first_app.cpp +++ b/src/first_app.cpp @@ -11,7 +11,15 @@ void FirstApp::run() { Chunk::load(); - loadGameObjects(); + 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)); + } + } SimpleRenderer renderer{xeEngine, Chunk::getTextures()}; @@ -44,26 +52,4 @@ void FirstApp::run() { } -void FirstApp::loadGameObjects() { - - for(int32_t x = 0; x < 10; x++) { - for(int32_t z = 0; z < 10; z++) { - Chunk* chunk = Chunk::newChunk(x, z, 53463); - } - } - - for(int32_t x = 0; x < 10; x++) { - for(int32_t z = 0; z < 10; z++) { - Chunk* chunk = Chunk::getChunk(x,z); - chunk->createMesh(); - - auto chunkObject = xe::GameObject::createGameObject(); - chunkObject.model = chunk->getMesh(); - chunkObject.transform.translation = {16.f*x, 0.f, 16.f*z}; - gameObjects.push_back(std::move(chunkObject)); - } - } - -} - }
\ No newline at end of file diff --git a/src/first_app.hpp b/src/first_app.hpp index 87cedba..3339b04 100755 --- a/src/first_app.hpp +++ b/src/first_app.hpp @@ -32,8 +32,6 @@ class FirstApp { static constexpr int WIDTH = 800; static constexpr int HEIGHT = 600; - void loadGameObjects(); - xe::Engine xeEngine; std::vector<xe::GameObject> gameObjects; diff --git a/src/simple_renderer.cpp b/src/simple_renderer.cpp index 17f7b57..22046be 100644 --- a/src/simple_renderer.cpp +++ b/src/simple_renderer.cpp @@ -1,4 +1,5 @@ #include "simple_renderer.hpp" +#include "chunk.hpp" namespace app { @@ -18,8 +19,6 @@ SimpleRenderer::SimpleRenderer(xe::Engine &xeEngine, std::vector<xe::Image*> &im void SimpleRenderer::render(std::vector<xe::GameObject> &gameObjects, xe::Camera &xeCamera) { - // xeRenderSystem->loadTexture(1, xeImage); - xeRenderSystem->start(); UniformBuffer ubo{}; @@ -30,6 +29,10 @@ 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); } |