summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortylermurphy534 <tylermurphy534@gmail.com>2022-09-28 19:36:35 -0400
committertylermurphy534 <tylermurphy534@gmail.com>2022-09-28 19:36:35 -0400
commitfdbe207540541b26d2800f87ddd77006d5fdf4f3 (patch)
treeec87219d904d2cf4e40f2487b5b795d6a99e5480 /src
parentonly wait for buffers once. fix chunk mesh edges (diff)
downloadminecraftvulkan-fdbe207540541b26d2800f87ddd77006d5fdf4f3.tar.gz
minecraftvulkan-fdbe207540541b26d2800f87ddd77006d5fdf4f3.tar.bz2
minecraftvulkan-fdbe207540541b26d2800f87ddd77006d5fdf4f3.zip
async chunk generation
Diffstat (limited to 'src')
-rw-r--r--src/chunk.cpp78
-rw-r--r--src/chunk.hpp9
-rwxr-xr-xsrc/first_app.cpp7
-rwxr-xr-xsrc/first_app.hpp2
4 files changed, 63 insertions, 33 deletions
diff --git a/src/chunk.cpp b/src/chunk.cpp
index 395aee7..2f7c969 100644
--- a/src/chunk.cpp
+++ b/src/chunk.cpp
@@ -12,7 +12,6 @@ Chunk::Chunk(int32_t gridX, int32_t gridZ, uint32_t world_seed)
gridX{gridX},
gridZ{gridZ} {
chunkMesh = nullptr;
- generate();
}
Chunk::~Chunk() {
@@ -98,6 +97,7 @@ void Chunk::unload() {
void Chunk::createMeshAsync(Chunk* c) {
if(c == nullptr) return;
if(c->working) return;
+ c->working = true;
if(c->worker.joinable())
c->worker.join();
c->worker = std::thread(createMesh, c);
@@ -105,6 +105,13 @@ void Chunk::createMeshAsync(Chunk* c) {
void Chunk::createMesh(Chunk* c) {
if(c == nullptr) return;
+ if(!isGenerated(c->gridX-1, c->gridZ) ||
+ !isGenerated(c->gridX+1, c->gridZ) ||
+ !isGenerated(c->gridX, c->gridZ-1) ||
+ !isGenerated(c->gridX, c->gridZ+1)) {
+ c->working = false;
+ return;
+ }
c->vertexData.data.clear();
for(int32_t x=0;x<16;x++) {
for(int32_t y=0; y<256; y++) {
@@ -132,8 +139,8 @@ void Chunk::createMesh(Chunk* c) {
}
}
}
+ c->reload = true;
c->working = false;
- c->reloadRequired = true;
}
void Chunk::addVerticies(Chunk* c, uint8_t side, int32_t x, int32_t y, int32_t z, uint8_t block) {
@@ -151,11 +158,47 @@ void Chunk::addVerticies(Chunk* c, uint8_t side, int32_t x, int32_t y, int32_t z
}
//
+// CHUNK GENERATION FOR BOTH SYNC AND ASYNC
+//
+
+void Chunk::generateAsync(Chunk* c) {
+ if(c == nullptr) return;
+ if(c->working) return;
+ c->working = true;
+ if(c->worker.joinable())
+ c->worker.join();
+ c->worker = std::thread(generate, c);
+}
+
+void Chunk::generate(Chunk* c) {
+ c->cubes.resize(16*16*256);
+
+ const PerlinNoise perlin{c->world_seed};
+
+ for(int x = 0; x < 16; x++) {
+ for(int z = 0; z < 16; z++) {
+ int height = perlin.octave2D_01((( x + c->gridX * 16) * 0.01), ((z + c->gridZ * 16) * 0.01), 4) * 20;
+ for(int y = 0; y < 256; y++) {
+ if(y == height){
+ c->setBlock(x, y, z, GRASS);
+ } else if(y < height)
+ c->setBlock(x, y, z, DIRT);
+ else
+ c->setBlock(x, y, z, AIR);
+ }
+ }
+ }
+
+ c->generated = true;
+ c->working = false;
+}
+
+//
// CHUNK GETTERS AND SETTORS
//
xe::Model* Chunk::getMesh() {
- if(reloadRequired) {
+ if(reload) {
if(chunkMesh != nullptr) {
xe::Model::deleteModel(chunkMesh);
chunkMesh = nullptr;
@@ -166,7 +209,8 @@ xe::Model* Chunk::getMesh() {
builder.vertexData = vertexData;
builder.vertexSize = 36;
chunkMesh = xe::Model::createModel(builder);
- reloadRequired = false;
+ vertexData.data.clear();
+ reload = false;
}
return chunkMesh;
}
@@ -207,28 +251,10 @@ void Chunk::setBlock(int32_t x, int32_t y, int32_t z, uint8_t block) {
cubes[index] = block;
}
-//
-// CHUNK GENERATION
-//
-
-void Chunk::generate() {
- cubes.resize(16*16*256);
-
- const PerlinNoise perlin{world_seed};
-
- for(int x = 0; x < 16; x++) {
- for(int z = 0; z < 16; z++) {
- int height = perlin.octave2D_01((( x + gridX * 16) * 0.01), ((z + gridZ * 16) * 0.01), 4) * 20;
- for(int y = 0; y < 256; y++) {
- if(y == height){
- setBlock(x, y, z, GRASS);
- } else if(y < height)
- setBlock(x, y, z, DIRT);
- else
- setBlock(x, y, z, AIR);
- }
- }
- }
+bool Chunk::isGenerated(int32_t gridX, int32_t gridZ) {
+ Chunk* chunk = Chunk::getChunk(gridX, gridZ);
+ if(chunk == nullptr) return false;
+ return chunk->generated;
}
} \ No newline at end of file
diff --git a/src/chunk.hpp b/src/chunk.hpp
index c53a0d3..734c07b 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -44,10 +44,15 @@ class Chunk {
static void createMesh(Chunk* c);
static void createMeshAsync(Chunk* c);
+ static void generate(Chunk* c);
+ static void generateAsync(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 bool isGenerated(int32_t gridX, int32_t gridZ);
+
const int32_t gridX, gridZ;
const uint32_t world_seed, chunk_seed;
@@ -56,10 +61,10 @@ class Chunk {
Chunk(int32_t gridX, int32_t gridZ, uint32_t world_seed);
~Chunk();
- void generate();
static void addVerticies(Chunk* c, uint8_t side, int32_t x, int32_t y, int32_t z, uint8_t block);
- bool reloadRequired{false};
+ bool generated{false};
+ bool reload{false};
bool working{false};
xe::Model* chunkMesh;
diff --git a/src/first_app.cpp b/src/first_app.cpp
index 6b6a80e..e677d06 100755
--- a/src/first_app.cpp
+++ b/src/first_app.cpp
@@ -78,11 +78,10 @@ void FirstApp::reloadLoadedChunks(xe::GameObject& viewer) {
Chunk* chunk = Chunk::getChunk(newGridX, newGridZ);
if(chunk == nullptr) {
chunk = Chunk::newChunk(newGridX, newGridZ, 12345);
+ Chunk::generateAsync(chunk);
+ }
+ if(chunk->getMesh() == nullptr){
Chunk::createMeshAsync(chunk);
- Chunk::createMeshAsync(Chunk::getChunk(newGridX+1, newGridZ));
- Chunk::createMeshAsync(Chunk::getChunk(newGridX-1, newGridZ));
- Chunk::createMeshAsync(Chunk::getChunk(newGridX, newGridZ+1));
- Chunk::createMeshAsync(Chunk::getChunk(newGridX, newGridZ-1));
}
gameObject.model = chunk->getMesh();
gameObject.transform.translation = glm::vec3(newGridX * 16.f, 0, newGridZ * 16.f);
diff --git a/src/first_app.hpp b/src/first_app.hpp
index d361296..dc912fb 100755
--- a/src/first_app.hpp
+++ b/src/first_app.hpp
@@ -32,7 +32,7 @@ class FirstApp {
static constexpr int WIDTH = 800;
static constexpr int HEIGHT = 600;
- static constexpr int RENDER_DISTANCE = 10;
+ static constexpr int RENDER_DISTANCE = 15;
void createGameObjects(xe::GameObject& viewer);
void reloadLoadedChunks(xe::GameObject& viewer);