async chunk generation
This commit is contained in:
parent
1f4dc3aa84
commit
fdbe207540
4 changed files with 63 additions and 33 deletions
|
@ -12,7 +12,6 @@ Chunk::Chunk(int32_t gridX, int32_t gridZ, uint32_t world_seed)
|
||||||
gridX{gridX},
|
gridX{gridX},
|
||||||
gridZ{gridZ} {
|
gridZ{gridZ} {
|
||||||
chunkMesh = nullptr;
|
chunkMesh = nullptr;
|
||||||
generate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunk::~Chunk() {
|
Chunk::~Chunk() {
|
||||||
|
@ -98,6 +97,7 @@ void Chunk::unload() {
|
||||||
void Chunk::createMeshAsync(Chunk* c) {
|
void Chunk::createMeshAsync(Chunk* c) {
|
||||||
if(c == nullptr) return;
|
if(c == nullptr) return;
|
||||||
if(c->working) return;
|
if(c->working) return;
|
||||||
|
c->working = true;
|
||||||
if(c->worker.joinable())
|
if(c->worker.joinable())
|
||||||
c->worker.join();
|
c->worker.join();
|
||||||
c->worker = std::thread(createMesh, c);
|
c->worker = std::thread(createMesh, c);
|
||||||
|
@ -105,6 +105,13 @@ void Chunk::createMeshAsync(Chunk* c) {
|
||||||
|
|
||||||
void Chunk::createMesh(Chunk* c) {
|
void Chunk::createMesh(Chunk* c) {
|
||||||
if(c == nullptr) return;
|
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();
|
c->vertexData.data.clear();
|
||||||
for(int32_t x=0;x<16;x++) {
|
for(int32_t x=0;x<16;x++) {
|
||||||
for(int32_t y=0; y<256; y++) {
|
for(int32_t y=0; y<256; y++) {
|
||||||
|
@ -132,8 +139,8 @@ void Chunk::createMesh(Chunk* c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c->reload = true;
|
||||||
c->working = false;
|
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) {
|
void Chunk::addVerticies(Chunk* c, uint8_t side, int32_t x, int32_t y, int32_t z, uint8_t block) {
|
||||||
|
@ -150,12 +157,48 @@ 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
|
// CHUNK GETTERS AND SETTORS
|
||||||
//
|
//
|
||||||
|
|
||||||
xe::Model* Chunk::getMesh() {
|
xe::Model* Chunk::getMesh() {
|
||||||
if(reloadRequired) {
|
if(reload) {
|
||||||
if(chunkMesh != nullptr) {
|
if(chunkMesh != nullptr) {
|
||||||
xe::Model::deleteModel(chunkMesh);
|
xe::Model::deleteModel(chunkMesh);
|
||||||
chunkMesh = nullptr;
|
chunkMesh = nullptr;
|
||||||
|
@ -166,7 +209,8 @@ xe::Model* Chunk::getMesh() {
|
||||||
builder.vertexData = vertexData;
|
builder.vertexData = vertexData;
|
||||||
builder.vertexSize = 36;
|
builder.vertexSize = 36;
|
||||||
chunkMesh = xe::Model::createModel(builder);
|
chunkMesh = xe::Model::createModel(builder);
|
||||||
reloadRequired = false;
|
vertexData.data.clear();
|
||||||
|
reload = false;
|
||||||
}
|
}
|
||||||
return chunkMesh;
|
return chunkMesh;
|
||||||
}
|
}
|
||||||
|
@ -207,28 +251,10 @@ void Chunk::setBlock(int32_t x, int32_t y, int32_t z, uint8_t block) {
|
||||||
cubes[index] = block;
|
cubes[index] = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
bool Chunk::isGenerated(int32_t gridX, int32_t gridZ) {
|
||||||
// CHUNK GENERATION
|
Chunk* chunk = Chunk::getChunk(gridX, gridZ);
|
||||||
//
|
if(chunk == nullptr) return false;
|
||||||
|
return chunk->generated;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -44,10 +44,15 @@ class Chunk {
|
||||||
static void createMesh(Chunk* c);
|
static void createMesh(Chunk* c);
|
||||||
static void createMeshAsync(Chunk* c);
|
static void createMeshAsync(Chunk* c);
|
||||||
|
|
||||||
|
static void generate(Chunk* c);
|
||||||
|
static void generateAsync(Chunk* c);
|
||||||
|
|
||||||
xe::Model* getMesh();
|
xe::Model* getMesh();
|
||||||
uint8_t getBlock(int32_t x, int32_t y, int32_t z);
|
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);
|
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 int32_t gridX, gridZ;
|
||||||
const uint32_t world_seed, chunk_seed;
|
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(int32_t gridX, int32_t gridZ, uint32_t world_seed);
|
||||||
~Chunk();
|
~Chunk();
|
||||||
|
|
||||||
void generate();
|
|
||||||
static void addVerticies(Chunk* c, 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 generated{false};
|
||||||
|
bool reload{false};
|
||||||
bool working{false};
|
bool working{false};
|
||||||
|
|
||||||
xe::Model* chunkMesh;
|
xe::Model* chunkMesh;
|
||||||
|
|
|
@ -78,11 +78,10 @@ void FirstApp::reloadLoadedChunks(xe::GameObject& viewer) {
|
||||||
Chunk* chunk = Chunk::getChunk(newGridX, newGridZ);
|
Chunk* chunk = Chunk::getChunk(newGridX, newGridZ);
|
||||||
if(chunk == nullptr) {
|
if(chunk == nullptr) {
|
||||||
chunk = Chunk::newChunk(newGridX, newGridZ, 12345);
|
chunk = Chunk::newChunk(newGridX, newGridZ, 12345);
|
||||||
|
Chunk::generateAsync(chunk);
|
||||||
|
}
|
||||||
|
if(chunk->getMesh() == nullptr){
|
||||||
Chunk::createMeshAsync(chunk);
|
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.model = chunk->getMesh();
|
||||||
gameObject.transform.translation = glm::vec3(newGridX * 16.f, 0, newGridZ * 16.f);
|
gameObject.transform.translation = glm::vec3(newGridX * 16.f, 0, newGridZ * 16.f);
|
||||||
|
|
|
@ -32,7 +32,7 @@ class FirstApp {
|
||||||
|
|
||||||
static constexpr int WIDTH = 800;
|
static constexpr int WIDTH = 800;
|
||||||
static constexpr int HEIGHT = 600;
|
static constexpr int HEIGHT = 600;
|
||||||
static constexpr int RENDER_DISTANCE = 10;
|
static constexpr int RENDER_DISTANCE = 15;
|
||||||
|
|
||||||
void createGameObjects(xe::GameObject& viewer);
|
void createGameObjects(xe::GameObject& viewer);
|
||||||
void reloadLoadedChunks(xe::GameObject& viewer);
|
void reloadLoadedChunks(xe::GameObject& viewer);
|
||||||
|
|
Loading…
Reference in a new issue