summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chunk.cpp191
-rw-r--r--src/chunk.hpp23
-rwxr-xr-xsrc/first_app.cpp32
-rwxr-xr-xsrc/first_app.hpp2
-rw-r--r--src/simple_renderer.cpp7
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);
}