Chunks render moved to ChunksLoader
This commit is contained in:
@@ -8,6 +8,7 @@ Chunk::Chunk(int xpos, int ypos, int zpos) : x(xpos), y(ypos), z(zpos){
|
||||
for (unsigned int i = 0; i < CHUNK_VOL; i++)
|
||||
voxels[i].id = 1;
|
||||
lightmap = new Lightmap();
|
||||
renderData.vertices = nullptr;
|
||||
}
|
||||
|
||||
Chunk::~Chunk(){
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef VOXELS_CHUNK_H_
|
||||
#define VOXELS_CHUNK_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CHUNK_W 16
|
||||
#define CHUNK_H 256
|
||||
#define CHUNK_D 16
|
||||
@@ -9,6 +11,11 @@
|
||||
class voxel;
|
||||
class Lightmap;
|
||||
|
||||
struct RenderData {
|
||||
float* vertices;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
class Chunk {
|
||||
public:
|
||||
int x,y,z;
|
||||
@@ -19,6 +26,8 @@ public:
|
||||
bool loaded = false;
|
||||
int surrounding = 0;
|
||||
int references = 1;
|
||||
RenderData renderData;
|
||||
|
||||
Chunk(int x, int y, int z);
|
||||
~Chunk();
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
|
||||
ChunksController::ChunksController(Chunks* chunks, Lighting* lighting) : chunks(chunks), lighting(lighting){
|
||||
loadersCount = std::thread::hardware_concurrency() - 1;
|
||||
loadersCount = std::thread::hardware_concurrency() * 2 - 1;
|
||||
if (loadersCount <= 0)
|
||||
loadersCount = 1;
|
||||
loaders = new ChunksLoader*[loadersCount];
|
||||
@@ -130,7 +130,7 @@ bool ChunksController::loadVisible(WorldFiles* worldFiles){
|
||||
oz += 1;
|
||||
closes[(oy * 3 + oz) * 3 + ox] = other;
|
||||
}
|
||||
freeLoader->perform(chunk, (Chunk**)closes);
|
||||
freeLoader->load(chunk, (Chunk**)closes);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -139,6 +139,35 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) {
|
||||
const int h = chunks->h;
|
||||
const int d = chunks->d;
|
||||
|
||||
for (int y = 0; y < h; y++){
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = (y * d + z) * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
if (chunk->renderData.vertices > (void*)1){
|
||||
const int chunk_attrs[] = {3,2,4, 0};
|
||||
Mesh* mesh = new Mesh(chunk->renderData.vertices, chunk->renderData.size / CHUNK_VERTEX_SIZE, chunk_attrs);
|
||||
chunks->meshes[index] = mesh;
|
||||
delete[] chunk->renderData.vertices;
|
||||
chunk->renderData.vertices = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ChunksLoader* freeLoader = nullptr;
|
||||
for (int i = 0; i < loadersCount; i++){
|
||||
ChunksLoader* loader = loaders[i];
|
||||
if (loader->isBusy()){
|
||||
continue;
|
||||
}
|
||||
freeLoader = loader;
|
||||
break;
|
||||
}
|
||||
if (freeLoader == nullptr)
|
||||
return false;
|
||||
|
||||
int nearX = 0;
|
||||
int nearY = 0;
|
||||
int nearZ = 0;
|
||||
@@ -208,9 +237,15 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) {
|
||||
oz += 1;
|
||||
closes[(oy * 3 + oz) * 3 + ox] = other;
|
||||
}
|
||||
mesh = renderer->render(chunk, (const Chunk**)closes);
|
||||
chunks->meshes[index] = mesh;
|
||||
return true;
|
||||
if (chunk->renderData.vertices == nullptr){
|
||||
chunk->renderData.vertices = (float*)1;
|
||||
freeLoader->render(chunk, (Chunk**)closes);
|
||||
|
||||
return true;
|
||||
}
|
||||
//mesh = renderer->render(chunk, (const Chunk**)closes);
|
||||
//chunks->meshes[index] = mesh;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Chunks.h"
|
||||
#include "WorldGenerator.h"
|
||||
#include "../lighting/Lighting.h"
|
||||
#include "../graphics/VoxelRenderer.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -13,7 +14,8 @@
|
||||
void ChunksLoader::_thread(){
|
||||
Chunks chunks(3,3,3, -1,-1,-1);
|
||||
Lighting lighting(&chunks);
|
||||
while (working){
|
||||
VoxelRenderer renderer;
|
||||
while (state != OFF){
|
||||
if (current == nullptr){
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
continue;
|
||||
@@ -27,12 +29,24 @@ void ChunksLoader::_thread(){
|
||||
}
|
||||
}
|
||||
|
||||
if (!chunk->loaded){
|
||||
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z);
|
||||
if (state == LOAD){
|
||||
chunks.putChunk(chunk);
|
||||
if (!chunk->loaded){
|
||||
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z);
|
||||
}
|
||||
|
||||
lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true);
|
||||
}
|
||||
else if (state == RENDER){
|
||||
size_t size;
|
||||
renderer.render(chunk, (const Chunk**)(closes.load()), size);
|
||||
float* vertices = new float[size];
|
||||
for (size_t i = 0; i < size; i++)
|
||||
vertices[i] = renderer.buffer[i];
|
||||
chunk->renderData.vertices = vertices;
|
||||
chunk->renderData.size = size;
|
||||
}
|
||||
|
||||
chunks.putChunk(chunk);
|
||||
lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true);
|
||||
chunks.clear(false);
|
||||
for (int i = 0; i < CLOSES_C; i++){
|
||||
Chunk* other = closes[i];
|
||||
@@ -45,7 +59,7 @@ void ChunksLoader::_thread(){
|
||||
}
|
||||
}
|
||||
|
||||
void ChunksLoader::perform(Chunk* chunk, Chunk** closes_passed){
|
||||
void ChunksLoader::perform(Chunk* chunk, Chunk** closes_passed, LoaderMode mode){
|
||||
if (isBusy()){
|
||||
std::cerr << "performing while busy" << std::endl;
|
||||
return;
|
||||
@@ -64,4 +78,13 @@ void ChunksLoader::perform(Chunk* chunk, Chunk** closes_passed){
|
||||
}
|
||||
}
|
||||
current = chunk;
|
||||
state = mode;
|
||||
}
|
||||
|
||||
void ChunksLoader::load(Chunk* chunk, Chunk** closes_passed){
|
||||
perform(chunk, closes_passed, LOAD);
|
||||
}
|
||||
|
||||
void ChunksLoader::render(Chunk* chunk, Chunk** closes_passed){
|
||||
perform(chunk, closes_passed, RENDER);
|
||||
}
|
||||
|
||||
@@ -12,19 +12,25 @@
|
||||
|
||||
class Chunk;
|
||||
|
||||
enum LoaderMode {
|
||||
OFF, IDLE, LOAD, RENDER,
|
||||
};
|
||||
|
||||
class ChunksLoader final {
|
||||
private:
|
||||
std::thread loaderThread;
|
||||
void _thread();
|
||||
std::atomic<Chunk*> current {nullptr};
|
||||
std::atomic<Chunk**> closes {nullptr};
|
||||
std::atomic<bool> working {true};
|
||||
std::atomic<LoaderMode> state {IDLE};
|
||||
|
||||
void perform(Chunk* chunk, Chunk** closes_passed, LoaderMode mode);
|
||||
public:
|
||||
ChunksLoader() : loaderThread{} {
|
||||
loaderThread = std::thread{&ChunksLoader::_thread, this};
|
||||
}
|
||||
~ChunksLoader(){
|
||||
working = false;
|
||||
state = OFF;
|
||||
loaderThread.join();
|
||||
}
|
||||
|
||||
@@ -32,10 +38,11 @@ public:
|
||||
return current != nullptr;
|
||||
}
|
||||
|
||||
void perform(Chunk* chunk, Chunk** closes_passed);
|
||||
void load(Chunk* chunk, Chunk** closes_passed);
|
||||
void render(Chunk* chunk, Chunk** closes_passed);
|
||||
|
||||
void stop(){
|
||||
working = false;
|
||||
state = OFF;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user