Séparation Chunk::Update et VertexBuffer::SetMeshData, Cleanup

This commit is contained in:
MarcEricMartel 2021-12-13 23:24:12 -05:00
parent 7eb9f44d41
commit e8a9cbb96e
7 changed files with 72 additions and 55 deletions

View File

@ -124,34 +124,38 @@ void Chunk::CheckNeighbors(int x, int z, World* world) {
void Chunk::GetPosition(int& x, int& y) const { x = m_posX; y = m_posY; } void Chunk::GetPosition(int& x, int& y) const { x = m_posX; y = m_posY; }
void Chunk::FlushMeshToVBO() {
m_vertexBuffer.SetMeshData(m_vd, m_vcount);
m_vcount = 0;
delete[] m_vd;
}
void Chunk::Update(BlockInfo* blockinfo[BTYPE_LAST], World* world) { void Chunk::Update(BlockInfo* blockinfo[BTYPE_LAST], World* world) {
float u, v, s; float u, v, s;
// Update mesh // Update mesh
if (m_isDirty) { if (m_isDirty) {
int maxVertexCount = (CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z) * (6 * 4); int maxVertexCount = (CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z) * (6 * 4);
VertexBuffer::VertexData* vd = new VertexBuffer::VertexData[maxVertexCount]; m_vd = new VertexBuffer::VertexData[maxVertexCount];
int count = 0; m_vcount = 0;
for (int x = 0; x < CHUNK_SIZE_X; ++x) { for (int x = 0; x < CHUNK_SIZE_X; ++x) {
for (int z = 0; z < CHUNK_SIZE_Z; ++z) { for (int z = 0; z < CHUNK_SIZE_Z; ++z) {
for (int y = 0; y < CHUNK_SIZE_Y; ++y) { for (int y = 0; y < CHUNK_SIZE_Y; ++y) {
if (count > USHRT_MAX) if (m_vcount > USHRT_MAX)
break; break;
BlockType bt = GetBlock(x, y, z); BlockType bt = GetBlock(x, y, z);
if (bt != BTYPE_AIR) { if (bt != BTYPE_AIR) {
blockinfo[bt]->GetTexture(u, v, s); blockinfo[bt]->GetTexture(u, v, s);
AddBlockToMesh(vd, count, bt, x, y, z, u, v, s, world); AddBlockToMesh(m_vd, m_vcount, bt, x, y, z, u, v, s, world);
} }
} }
} }
} }
if (count > USHRT_MAX) { if (m_vcount > USHRT_MAX) {
count = USHRT_MAX; m_vcount = USHRT_MAX;
std::cout << "[ Chunk :: Update ] Chunk data truncaned , too much vertices to have a 16 bit index " << std::endl; std::cout << "[ Chunk :: Update ] Chunk data truncaned , too much vertices to have a 16 bit index " << std::endl;
} }
m_vertexBuffer.SetMeshData(vd, count);
delete[] vd;
} }
m_isDirty = false; m_isDirty = false;
} }

View File

@ -18,6 +18,9 @@ class Chunk {
int m_posX; // Position du chunk dans l'array constituant le monde. int m_posX; // Position du chunk dans l'array constituant le monde.
int m_posY; int m_posY;
VertexBuffer::VertexData* m_vd;
int m_vcount;
void AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z, float u, float v, float s, World* world); void AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType bt, int x, int y, int z, float u, float v, float s, World* world);
public: public:
@ -30,7 +33,9 @@ class Chunk {
void CheckNeighbors(int x, int z, World* world); void CheckNeighbors(int x, int z, World* world);
void GetPosition(int& x, int& y) const; void GetPosition(int& x, int& y) const;
void Update(BlockInfo* blockinfo[BTYPE_LAST], World* world); void Update(BlockInfo* blockinfo[BTYPE_LAST], World* world);
void FlushMeshToVBO();
void Render() const; void Render() const;
bool IsDirty() const; bool IsDirty() const;

View File

@ -42,8 +42,8 @@
#define FRAMES_UPDATE_CHUNKS 1 #define FRAMES_UPDATE_CHUNKS 1
#define FRAMES_DELETE_CHUNKS 1 #define FRAMES_DELETE_CHUNKS 1
#define THREADS_GENERATE_CHUNKS 10 #define THREADS_GENERATE_CHUNKS 12
#define THREADS_UPDATE_CHUNKS 10 #define THREADS_UPDATE_CHUNKS 8
#define VIEW_DISTANCE 1024 #define VIEW_DISTANCE 1024
#define TEXTURE_SIZE 512 #define TEXTURE_SIZE 512

View File

@ -280,37 +280,37 @@ void Engine::KeyPressEvent(unsigned char key) {
break; break;
case 22: // W case 22: // W
if (!m_keyW) { if (!m_keyW) {
std::cout << "W " << std::endl; // std::cout << "W " << std::endl;
m_keyW = true; m_keyW = true;
} }
break; break;
case 0: // A case 0: // A
if (!m_keyA) { if (!m_keyA) {
std::cout << "A " << std::endl; //std::cout << "A " << std::endl;
m_keyA = true; m_keyA = true;
} }
break; break;
case 18: // S case 18: // S
if (!m_keyS) { if (!m_keyS) {
std::cout << "S " << std::endl; //std::cout << "S " << std::endl;
m_keyS = true; m_keyS = true;
} }
break; break;
case 3: // D case 3: // D
if (!m_keyD) { if (!m_keyD) {
std::cout << "D " << std::endl; //std::cout << "D " << std::endl;
m_keyD = true; m_keyD = true;
} }
break; break;
case 38: // Left Shift case 38: // Left Shift
if (!m_keylshift) { if (!m_keylshift) {
std::cout << "Dash!" << std::endl; //std::cout << "Dash!" << std::endl;
m_keylshift = true; m_keylshift = true;
} }
break; break;
case 57: // Space case 57: // Space
if (!m_keySpace) { if (!m_keySpace) {
std::cout << "Jump! " << std::endl; //std::cout << "Jump! " << std::endl;
m_keySpace = true; m_keySpace = true;
} }
break; break;
@ -344,26 +344,26 @@ void Engine::KeyReleaseEvent(unsigned char key) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break; break;
case 22: // W case 22: // W
std::cout << "rW " << std::endl; //std::cout << "rW " << std::endl;
m_keyW = false; m_keyW = false;
break; break;
case 0: // A case 0: // A
std::cout << "rA " << std::endl; //std::cout << "rA " << std::endl;
m_keyA = false; m_keyA = false;
break; break;
case 18: // S case 18: // S
std::cout << "rS " << std::endl; //std::cout << "rS " << std::endl;
m_keyS = false; m_keyS = false;
break; break;
case 3: // D case 3: // D
std::cout << "rD " << std::endl; //std::cout << "rD " << std::endl;
m_keyD = false; m_keyD = false;
break; break;
case 38: // Left Shift case 38: // Left Shift
std::cout << "rLS " << std::endl; //std::cout << "rLS " << std::endl;
m_keylshift = false; m_keylshift = false;
case 57: // Espace case 57: // Espace
std::cout << "rSpace " << std::endl; //std::cout << "rSpace " << std::endl;
m_keySpace = false; m_keySpace = false;
break; break;
} }

View File

@ -16,10 +16,10 @@ bool VertexBuffer::IsValid() const {
return m_isValid; return m_isValid;
} }
std::mutex VertexBuffer::m_opgl; //std::mutex VertexBuffer::m_opgl;
void VertexBuffer::SetMeshData(VertexData* vd, int vertexCount) { void VertexBuffer::SetMeshData(VertexData* vd, int vertexCount) {
const std::lock_guard<std::mutex> prout(VertexBuffer::m_opgl); //const std::lock_guard<std::mutex> prout(VertexBuffer::m_opgl);
assert(vertexCount <= USHRT_MAX); assert(vertexCount <= USHRT_MAX);
if(vertexCount == 0) if(vertexCount == 0)
return; return;

View File

@ -34,7 +34,7 @@ class VertexBuffer
private: private:
static std::mutex m_opgl; // static std::mutex m_opgl;
bool m_isValid; bool m_isValid;
int m_vertexCount; int m_vertexCount;
GLuint m_vertexVboId; GLuint m_vertexVboId;

View File

@ -51,34 +51,42 @@ void World::TransposeWorld(Player& player, Bullet* bullets[MAX_BULLETS]) {
if (x > 0) { if (x > 0) {
for (int ax = 0; ax < WORLD_SIZE_X; ++ax) for (int ax = 0; ax < WORLD_SIZE_X; ++ax)
for (int ay = 0; ay < WORLD_SIZE_Y; ++ay) for (int ay = 0; ay < WORLD_SIZE_Y; ++ay)
if (ax - x >= 0) if (ax - x >= 0) {
m_chunks.Set(ax - x, ay, m_chunks.Set(ax - x, ay,
m_chunks.Remove(ax, ay)); m_chunks.Remove(ax, ay));
if (ax == WORLD_SIZE_X - 1) m_chunks.Get(ax - x, ay)->MakeDirty();
}
else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay)); else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay));
} }
else if (x < 0) { else if (x < 0) {
for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax) for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax)
for (int ay = WORLD_SIZE_Y - 1; ay >= 0; --ay) for (int ay = WORLD_SIZE_Y - 1; ay >= 0; --ay)
if (ax - x < WORLD_SIZE_X) if (ax - x < WORLD_SIZE_X) {
m_chunks.Set(ax - x, ay, m_chunks.Set(ax - x, ay,
m_chunks.Remove(ax, ay)); m_chunks.Remove(ax, ay));
if (ax + x == 0) m_chunks.Get(ax + x, ay)->MakeDirty();
}
else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay)); else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay));
} }
if (y > 0) { if (y > 0) {
for (int ax = 0; ax < WORLD_SIZE_X; ++ax) for (int ax = 0; ax < WORLD_SIZE_X; ++ax)
for (int ay = 0; ay < WORLD_SIZE_Y; ++ay) for (int ay = 0; ay < WORLD_SIZE_Y; ++ay)
if (ay - y >= 0) if (ay - y >= 0) {
m_chunks.Set(ax, ay - y, m_chunks.Set(ax, ay - y,
m_chunks.Remove(ax, ay)); m_chunks.Remove(ax, ay));
if (ay == WORLD_SIZE_Y) m_chunks.Get(ax, ay - y)->MakeDirty();
}
else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay)); else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay));
} }
else if (y < 0) { else if (y < 0) {
for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax) for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax)
for (int ay = WORLD_SIZE_Y - 1; ay >= 0; --ay) for (int ay = WORLD_SIZE_Y - 1; ay >= 0; --ay)
if (ay - y < WORLD_SIZE_Y) if (ay - y < WORLD_SIZE_Y) {
m_chunks.Set(ax, ay - y, m_chunks.Set(ax, ay - y,
m_chunks.Remove(ax, ay)); m_chunks.Remove(ax, ay));
if (ay - x == 0) m_chunks.Get(ax, ay - y)->MakeDirty();
}
else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay)); else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay));
} }
@ -289,14 +297,14 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY
int side = 0; int side = 0;
int threads = 0; int threads = 0;
std::future<Chunk*> genThList[THREADS_GENERATE_CHUNKS]; std::future<Chunk*> genThList[THREADS_GENERATE_CHUNKS];
//std::future<Chunk*> updateThList[THREADS_UPDATE_CHUNKS]; std::future<Chunk*> updateThList[THREADS_UPDATE_CHUNKS];
if (frameGenerate > 0) --frameGenerate; if (frameGenerate > 0) --frameGenerate;
if (frameUpdate > 0) --frameUpdate; if (frameUpdate > 0) --frameUpdate;
if (frameDelete > 0) --frameDelete; if (frameDelete > 0) --frameDelete;
if (!frameGenerate) if (!frameGenerate)
while (side * CHUNK_SIZE_X <= VIEW_DISTANCE * 2) { while (side * CHUNK_SIZE_X <= VIEW_DISTANCE * 2 + CHUNK_SIZE_X) {
int tx = -side, ty = -side; int tx = -side, ty = -side;
int chx = 0; int chx = 0;
int chy = 0; int chy = 0;
@ -370,10 +378,13 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY
break; break;
int chx = cx + tx * CHUNK_SIZE_X; int chx = cx + tx * CHUNK_SIZE_X;
int chy = cy + ty * CHUNK_SIZE_Z; int chy = cy + ty * CHUNK_SIZE_Z;
if (ChunkAt(chx, 1, chy) && if (ChunkAt(chx, 1, chy) &&
ChunkAt(chx, 1, chy)->IsDirty()) { ChunkAt(chx, 1, chy)->IsDirty()) {
ChunkAt(chx, 1, chy)->Update(blockinfo, this); updateThList[threads++] =
if (threads++ == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS; std::async(std::launch::async,
[](Chunk* chunk, BlockInfo* blockinfo[BTYPE_LAST], World* world) {
chunk->Update(blockinfo, world); return chunk; }, ChunkAt(chx, 1, chy), blockinfo, this);
if (threads == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS;
} }
} }
for (; ty <= side; ++ty) { for (; ty <= side; ++ty) {
@ -381,10 +392,13 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY
break; break;
int chx = cx + tx * CHUNK_SIZE_X; int chx = cx + tx * CHUNK_SIZE_X;
int chy = cy + ty * CHUNK_SIZE_Z; int chy = cy + ty * CHUNK_SIZE_Z;
if (ChunkAt(chx, 1, chy) && if (ChunkAt(chx, 1, chy) &&
ChunkAt(chx, 1, chy)->IsDirty()) { ChunkAt(chx, 1, chy)->IsDirty()) {
ChunkAt(chx, 1, chy)->Update(blockinfo, this); updateThList[threads++] =
if (threads++ == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS; std::async(std::launch::async,
[](Chunk* chunk, BlockInfo* blockinfo[BTYPE_LAST], World* world) {
chunk->Update(blockinfo, world); return chunk; }, ChunkAt(chx, 1, chy), blockinfo, this);
if (threads == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS;
} }
} }
for (; tx >= -side; --tx) { for (; tx >= -side; --tx) {
@ -392,10 +406,13 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY
break; break;
int chx = cx + tx * CHUNK_SIZE_X; int chx = cx + tx * CHUNK_SIZE_X;
int chy = cy + ty * CHUNK_SIZE_Z; int chy = cy + ty * CHUNK_SIZE_Z;
if (ChunkAt(chx, 1, chy) && if (ChunkAt(chx, 1, chy) &&
ChunkAt(chx, 1, chy)->IsDirty()) { ChunkAt(chx, 1, chy)->IsDirty()) {
ChunkAt(chx, 1, chy)->Update(blockinfo, this); updateThList[threads++] =
if (threads++ == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS; std::async(std::launch::async,
[](Chunk* chunk, BlockInfo* blockinfo[BTYPE_LAST], World* world) {
chunk->Update(blockinfo, world); return chunk; }, ChunkAt(chx, 1, chy), blockinfo, this);
if (threads == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS;
} }
} }
for (; ty >= -side; --ty) { for (; ty >= -side; --ty) {
@ -403,36 +420,27 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY
break; break;
int chx = cx + tx * CHUNK_SIZE_X; int chx = cx + tx * CHUNK_SIZE_X;
int chy = cy + ty * CHUNK_SIZE_Z; int chy = cy + ty * CHUNK_SIZE_Z;
if (ChunkAt(chx, 1, chy) && if (ChunkAt(chx, 1, chy) &&
ChunkAt(chx, 1, chy)->IsDirty()) {
ChunkAt(chx, 1, chy)->Update(blockinfo, this);
if (threads++ == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS;
}
/*if (ChunkAt(chx, 1, chy) && // Version multithread d'UpdateChunks qui ne fonctionne pas.
ChunkAt(chx, 1, chy)->IsDirty()) { ChunkAt(chx, 1, chy)->IsDirty()) {
updateThList[threads++] = updateThList[threads++] =
std::async(std::launch::async, std::async(std::launch::async,
[](Chunk* chunk, BlockInfo* blockinfo[BTYPE_LAST], World* world) { [](Chunk* chunk, BlockInfo* blockinfo[BTYPE_LAST], World* world) {
chunk->Update(blockinfo, world); return chunk; }, ChunkAt(chx, 1, chy), blockinfo, this); chunk->Update(blockinfo, world); return chunk; }, ChunkAt(chx, 1, chy), blockinfo, this);
if (threads == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS; if (threads == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS;
}*/ }
} }
if (frameUpdate) if (frameUpdate)
break; break;
++side; ++side;
} }
/*if (threads > 0) { if (threads > 0) {
for (int i = 0; i < threads; ++i)
updateThList[i].wait();
for (int i = 0; i < threads; ++i) { for (int i = 0; i < threads; ++i) {
int x, y; updateThList[i].wait();
Chunk* chunk = updateThList[i].get(); Chunk* chunk = updateThList[i].get();
chunk->GetPosition(x, y); chunk->FlushMeshToVBO();
m_chunks.Set(x - m_center[0], y - m_center[1], chunk);
} }
}*/ }
CleanUpWorld(frameDelete); CleanUpWorld(frameDelete);
} }