Removed the GameInstance::genChunks & Added World::genChunk
parent
9812d6adcf
commit
a62cadb408
|
@ -11,7 +11,6 @@ BlockAtlas::BlockAtlas(TextureAtlas *textureAtlas) {
|
|||
|
||||
void BlockAtlas::registerBlock(BlockDef* def) {
|
||||
definitions.push_back(def);
|
||||
std::cout << "Registered block" << std::endl;
|
||||
}
|
||||
|
||||
BlockDef* BlockAtlas::getBlock(int id) {
|
||||
|
|
|
@ -26,7 +26,7 @@ void MeshGenerator::build(BlockChunk* chunk, BlockAtlas* atlas,
|
|||
glm::vec3 check;
|
||||
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (chunk->getBlock(i) == 1) {
|
||||
if (chunk->getBlock(i) != 0) {
|
||||
ArrayTrans3D::indAssignVec(i, &off);
|
||||
BlockModel* model = atlas->getBlock(chunk->getBlock(i))->getModel();
|
||||
|
||||
|
|
|
@ -7,39 +7,6 @@
|
|||
|
||||
GameInstance::GameInstance() = default;
|
||||
|
||||
//TODO: Remove this function
|
||||
void genChunks(World* world) {
|
||||
PerlinNoise p(0);
|
||||
|
||||
int VIEW_RANGE = 24;
|
||||
|
||||
for (int i = -VIEW_RANGE; i < VIEW_RANGE; i++) {
|
||||
for (int j = -VIEW_RANGE; j < VIEW_RANGE; j++) {
|
||||
for (int k = -1; k < 1; k++) {
|
||||
|
||||
auto* blocks = new std::vector<int>();
|
||||
blocks->reserve(4096);
|
||||
|
||||
glm::vec3 innerPos, pos;
|
||||
|
||||
for (int ind = 0; ind < 4096; ind++) {
|
||||
ArrayTrans3D::indAssignVec(ind, &innerPos);
|
||||
pos.x = innerPos.x + i * CHUNK_SIZE;
|
||||
pos.y = innerPos.y + k * CHUNK_SIZE;
|
||||
pos.z = innerPos.z + j * CHUNK_SIZE;
|
||||
|
||||
double val = p.noise(pos.x / (double) 32, pos.z / (double) 32, pos.y / (double) 16) - pos.y * 0.08;
|
||||
|
||||
blocks->push_back((int)(val > 0.5));
|
||||
}
|
||||
|
||||
world->newChunk(new glm::vec3(i, k, j), new BlockChunk(blocks));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GameInstance::initialize(Renderer* renderer) {
|
||||
this->renderer = renderer;
|
||||
|
||||
|
@ -59,7 +26,16 @@ void GameInstance::initialize(Renderer* renderer) {
|
|||
//The world requires the blockAtlas for meshing and handling inputs.
|
||||
world = new World(blockAtlas);
|
||||
|
||||
genChunks(world);
|
||||
int SIZE = 16;
|
||||
for (int i = -SIZE; i < SIZE; i++) {
|
||||
for (int j = -4; j < 4; j++) {
|
||||
for (int k = -SIZE; k < SIZE; k++) {
|
||||
world->genChunk(new glm::vec3(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// genChunks(world);
|
||||
}
|
||||
|
||||
void GameInstance::update(GLfloat deltaTime) {
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
//
|
||||
|
||||
#include "World.h"
|
||||
#include "../engine/PerlinNoise.h"
|
||||
#include "../engine/helpers/ArrayTrans3D.h"
|
||||
|
||||
World::World() {
|
||||
blockAtlas = nullptr;
|
||||
|
@ -12,24 +14,89 @@ World::World(BlockAtlas *atlas) {
|
|||
blockAtlas = atlas;
|
||||
}
|
||||
|
||||
void World::genChunk(glm::vec3* pos) {
|
||||
chunkGenQueue.insert(pos);
|
||||
}
|
||||
|
||||
void World::newChunk(glm::vec3* pos, BlockChunk *c) {
|
||||
blockChunks.insert(std::pair<glm::vec3*, BlockChunk*>(pos, c));
|
||||
meshGenQueue.insert(pos);
|
||||
}
|
||||
|
||||
void genThread(World::ThreadData* t) {
|
||||
void chunkGenThread(World::ChunkThreadData *t) {
|
||||
PerlinNoise p(0);
|
||||
|
||||
auto* blocks = new std::vector<int>();
|
||||
blocks->reserve(4096);
|
||||
|
||||
glm::vec3 innerPos, pos;
|
||||
|
||||
for (int ind = 0; ind < 4096; ind++) {
|
||||
ArrayTrans3D::indAssignVec(ind, &innerPos);
|
||||
|
||||
pos.x = innerPos.x + t->pos->x * CHUNK_SIZE;
|
||||
pos.y = innerPos.y + t->pos->y * CHUNK_SIZE;
|
||||
pos.z = innerPos.z + t->pos->z * CHUNK_SIZE;
|
||||
|
||||
double val = p.noise(pos.x / (double) 32, pos.z / (double) 32, 0) * 16 - pos.y;
|
||||
|
||||
int block = (val > 0) ? (val > 1 ) ? (val > 4) ? 3 : 2 : 1 : 0;
|
||||
blocks->push_back(block);
|
||||
}
|
||||
|
||||
t->chunk = new BlockChunk(blocks);
|
||||
t->done = true;
|
||||
}
|
||||
|
||||
void meshGenThread(World::MeshThreadData *t) {
|
||||
MeshGenerator().build(t->chunk, t->atlas, *(t->vertices), *(t->indices));
|
||||
t->done = true;
|
||||
}
|
||||
|
||||
void World::update() {
|
||||
int done = 0;
|
||||
//Finish Block Gen threads
|
||||
for (auto iter = chunkGenThreads.begin(); iter != chunkGenThreads.end(); ) {
|
||||
ChunkThreadData* threadData = (*iter);
|
||||
|
||||
//If the threadData is done, create a BlockChunk and delete the threadData.
|
||||
if (threadData->done) {
|
||||
done++;
|
||||
// blockChunks.insert(std::pair<glm::vec3*, BlockChunk*>(threadData->pos, threadData->chunk));
|
||||
newChunk(threadData->pos, threadData->chunk);
|
||||
|
||||
delete threadData;
|
||||
|
||||
iter = chunkGenThreads.erase(iter);
|
||||
}
|
||||
//Otherwise ignore it and move to the next BlockChunk
|
||||
else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
//Create threads for the chunk generation.
|
||||
while (!chunkGenQueue.empty() && chunkGenThreads.size() < MAX_CHUNK_GEN_THREADS) {
|
||||
//Get and remove the first position from the vector.
|
||||
auto it = chunkGenQueue.begin();
|
||||
chunkGenQueue.erase(chunkGenQueue.begin());
|
||||
glm::vec3* pos = (*it);
|
||||
|
||||
//Create a thread for it and add the threadData to the chunkGenThreads vector
|
||||
auto t = new ChunkThreadData(pos, blockAtlas);
|
||||
auto thread = new std::thread(chunkGenThread, t);
|
||||
thread->detach();
|
||||
t->thread = thread;
|
||||
chunkGenThreads.push_back(t);
|
||||
}
|
||||
|
||||
//Run through all of the active generation threads, and finish and remove the ones that are ready to be finished.
|
||||
//Then, spin up new threads when there is space in the genThreads array and there are chunks waiting to be meshed.
|
||||
//Then, spin up new threads when there is space in the meshGenThreads array and there are chunks waiting to be meshed.
|
||||
|
||||
//Create MeshChunks for the finished threads.
|
||||
Timer applyGlobal("Applying Meshes");
|
||||
for (auto iter = genThreads.begin(); iter != genThreads.end(); ) {
|
||||
ThreadData* threadData = (*iter);
|
||||
for (auto iter = meshGenThreads.begin(); iter != meshGenThreads.end(); ) {
|
||||
MeshThreadData* threadData = (*iter);
|
||||
|
||||
//If the threadData is done, create a MeshChunk and delete the threadData.
|
||||
if (threadData->done) {
|
||||
|
@ -44,29 +111,30 @@ void World::update() {
|
|||
// apply.elapsedMs();
|
||||
|
||||
delete threadData;
|
||||
iter = genThreads.erase(iter);
|
||||
iter = meshGenThreads.erase(iter);
|
||||
}
|
||||
//Otherwise ignore it and move to the next MeshChunk
|
||||
else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
// applyGlobal.elapsedMs();
|
||||
|
||||
//Begin processing queued chunks if there are chunks to be processed and there's room for more threads.
|
||||
while (!meshGenQueue.empty() && genThreads.size() < MAX_CONCURRENT_THREADS) {
|
||||
while (!meshGenQueue.empty() && meshGenThreads.size() < MAX_MESH_GEN_THREADS) {
|
||||
|
||||
//Get and remove the first position from the vector.
|
||||
auto it = meshGenQueue.begin();
|
||||
meshGenQueue.erase(meshGenQueue.begin());
|
||||
glm::vec3* pos = (*it);
|
||||
|
||||
//Create a thread for it and add the threadData to the genThreads vector
|
||||
auto t = new ThreadData(pos, blockChunks.at(pos), blockAtlas);
|
||||
auto thread = new std::thread(genThread, t);
|
||||
//Create a thread for it and add the threadData to the meshGenThreads vector
|
||||
auto t = new MeshThreadData(pos, blockChunks.at(pos), blockAtlas);
|
||||
auto thread = new std::thread(meshGenThread, t);
|
||||
thread->detach();
|
||||
t->thread = thread;
|
||||
genThreads.push_back(t);
|
||||
meshGenThreads.push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +142,7 @@ std::map<glm::vec3*, MeshChunk*>* World::getMeshChunks() {
|
|||
return &meshChunks;
|
||||
}
|
||||
|
||||
World::ThreadData::ThreadData(glm::vec3 *pos, BlockChunk *chunk, BlockAtlas *atlas) {
|
||||
World::MeshThreadData::MeshThreadData(glm::vec3 *pos, BlockChunk *chunk, BlockAtlas *atlas) {
|
||||
this->pos = pos;
|
||||
this->chunk = chunk;
|
||||
this->atlas = atlas;
|
||||
|
@ -83,11 +151,23 @@ World::ThreadData::ThreadData(glm::vec3 *pos, BlockChunk *chunk, BlockAtlas *atl
|
|||
this->indices = new std::vector<unsigned int>();
|
||||
}
|
||||
|
||||
World::ThreadData::~ThreadData() {
|
||||
World::MeshThreadData::~MeshThreadData() {
|
||||
//Not delete this->pos because it is used in the MeshChunk and BlockChunk vectors.
|
||||
//delete pos
|
||||
delete vertices;
|
||||
delete indices;
|
||||
//Delete the thread, when the deconstructor is called, the thread is done.
|
||||
delete thread;
|
||||
}
|
||||
|
||||
World::ChunkThreadData::ChunkThreadData(glm::vec3 *pos, BlockAtlas *atlas) {
|
||||
this->pos = pos;
|
||||
this->atlas = atlas;
|
||||
this->done = false;
|
||||
this->chunk = nullptr;
|
||||
}
|
||||
|
||||
World::ChunkThreadData::~ChunkThreadData() {
|
||||
//Delete the thread, when the deconstructor is called, the thread is done.
|
||||
delete thread;
|
||||
}
|
|
@ -21,6 +21,7 @@ public:
|
|||
World();
|
||||
explicit World(BlockAtlas* atlas);
|
||||
|
||||
void genChunk(glm::vec3* pos);
|
||||
void newChunk(glm::vec3* pos, BlockChunk* c);
|
||||
|
||||
void update();
|
||||
|
@ -29,8 +30,8 @@ public:
|
|||
|
||||
~World() = default;
|
||||
|
||||
struct ThreadData {
|
||||
ThreadData(glm::vec3* pos, BlockChunk* chunk, BlockAtlas* atlas);
|
||||
struct MeshThreadData {
|
||||
MeshThreadData(glm::vec3* pos, BlockChunk* chunk, BlockAtlas* atlas);
|
||||
|
||||
std::thread* thread;
|
||||
|
||||
|
@ -43,7 +44,22 @@ public:
|
|||
std::vector<float>* vertices;
|
||||
std::vector<unsigned int>* indices;
|
||||
|
||||
~ThreadData();
|
||||
~MeshThreadData();
|
||||
};
|
||||
|
||||
struct ChunkThreadData {
|
||||
ChunkThreadData(glm::vec3* pos, BlockAtlas* atlas);
|
||||
|
||||
std::thread* thread;
|
||||
|
||||
glm::vec3* pos;
|
||||
BlockAtlas* atlas;
|
||||
|
||||
bool done;
|
||||
|
||||
BlockChunk* chunk;
|
||||
|
||||
~ChunkThreadData();
|
||||
};
|
||||
private:
|
||||
//Note to self:
|
||||
|
@ -52,10 +68,17 @@ private:
|
|||
std::map<glm::vec3*, BlockChunk*> blockChunks;
|
||||
std::map<glm::vec3*, MeshChunk*> meshChunks;
|
||||
|
||||
const int MAX_CONCURRENT_THREADS = 32;
|
||||
//TODO: Replace this BiQueueThreadArray model with a BiQueueThreadPool model (it's in the name)
|
||||
|
||||
//Chunk Gen BiQueue Variables
|
||||
const int MAX_CHUNK_GEN_THREADS = 16;
|
||||
std::unordered_set<glm::vec3*> chunkGenQueue;
|
||||
std::vector<ChunkThreadData*> chunkGenThreads;
|
||||
|
||||
//Mesh Gen BiQueue Variables
|
||||
const int MAX_MESH_GEN_THREADS = 64;
|
||||
std::unordered_set<glm::vec3*> meshGenQueue;
|
||||
std::vector<ThreadData*> genThreads;
|
||||
std::vector<MeshThreadData*> meshGenThreads;
|
||||
|
||||
BlockAtlas* blockAtlas;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue