diff --git a/SQCSim2021/chunk.cpp b/SQCSim2021/chunk.cpp index 97a12a6..2942b36 100644 --- a/SQCSim2021/chunk.cpp +++ b/SQCSim2021/chunk.cpp @@ -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::FlushMeshToVBO() { + m_vertexBuffer.SetMeshData(m_vd, m_vcount); + m_vcount = 0; + delete[] m_vd; +} + void Chunk::Update(BlockInfo* blockinfo[BTYPE_LAST], World* world) { float u, v, s; // Update mesh if (m_isDirty) { int maxVertexCount = (CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z) * (6 * 4); - VertexBuffer::VertexData* vd = new VertexBuffer::VertexData[maxVertexCount]; - int count = 0; + m_vd = new VertexBuffer::VertexData[maxVertexCount]; + m_vcount = 0; for (int x = 0; x < CHUNK_SIZE_X; ++x) { for (int z = 0; z < CHUNK_SIZE_Z; ++z) { for (int y = 0; y < CHUNK_SIZE_Y; ++y) { - if (count > USHRT_MAX) + if (m_vcount > USHRT_MAX) break; BlockType bt = GetBlock(x, y, z); if (bt != BTYPE_AIR) { 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) { - count = USHRT_MAX; + if (m_vcount > USHRT_MAX) { + m_vcount = USHRT_MAX; 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; } diff --git a/SQCSim2021/chunk.h b/SQCSim2021/chunk.h index e1863d3..e578999 100644 --- a/SQCSim2021/chunk.h +++ b/SQCSim2021/chunk.h @@ -18,6 +18,9 @@ class Chunk { int m_posX; // Position du chunk dans l'array constituant le monde. 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); public: @@ -30,7 +33,9 @@ class Chunk { void CheckNeighbors(int x, int z, World* world); void GetPosition(int& x, int& y) const; + void Update(BlockInfo* blockinfo[BTYPE_LAST], World* world); + void FlushMeshToVBO(); void Render() const; bool IsDirty() const; diff --git a/SQCSim2021/define.h b/SQCSim2021/define.h index 0bfdde7..4b05c2d 100644 --- a/SQCSim2021/define.h +++ b/SQCSim2021/define.h @@ -42,8 +42,8 @@ #define FRAMES_UPDATE_CHUNKS 1 #define FRAMES_DELETE_CHUNKS 1 -#define THREADS_GENERATE_CHUNKS 10 -#define THREADS_UPDATE_CHUNKS 10 +#define THREADS_GENERATE_CHUNKS 12 +#define THREADS_UPDATE_CHUNKS 8 #define VIEW_DISTANCE 1024 #define TEXTURE_SIZE 512 diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index 3058c86..70bfe0f 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -280,37 +280,37 @@ void Engine::KeyPressEvent(unsigned char key) { break; case 22: // W if (!m_keyW) { - std::cout << "W " << std::endl; + // std::cout << "W " << std::endl; m_keyW = true; } break; case 0: // A if (!m_keyA) { - std::cout << "A " << std::endl; + //std::cout << "A " << std::endl; m_keyA = true; } break; case 18: // S if (!m_keyS) { - std::cout << "S " << std::endl; + //std::cout << "S " << std::endl; m_keyS = true; } break; case 3: // D if (!m_keyD) { - std::cout << "D " << std::endl; + //std::cout << "D " << std::endl; m_keyD = true; } break; case 38: // Left Shift if (!m_keylshift) { - std::cout << "Dash!" << std::endl; + //std::cout << "Dash!" << std::endl; m_keylshift = true; } break; case 57: // Space if (!m_keySpace) { - std::cout << "Jump! " << std::endl; + //std::cout << "Jump! " << std::endl; m_keySpace = true; } break; @@ -344,26 +344,26 @@ void Engine::KeyReleaseEvent(unsigned char key) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; case 22: // W - std::cout << "rW " << std::endl; + //std::cout << "rW " << std::endl; m_keyW = false; break; case 0: // A - std::cout << "rA " << std::endl; + //std::cout << "rA " << std::endl; m_keyA = false; break; case 18: // S - std::cout << "rS " << std::endl; + //std::cout << "rS " << std::endl; m_keyS = false; break; case 3: // D - std::cout << "rD " << std::endl; + //std::cout << "rD " << std::endl; m_keyD = false; break; case 38: // Left Shift - std::cout << "rLS " << std::endl; + //std::cout << "rLS " << std::endl; m_keylshift = false; case 57: // Espace - std::cout << "rSpace " << std::endl; + //std::cout << "rSpace " << std::endl; m_keySpace = false; break; } diff --git a/SQCSim2021/vertexbuffer.cpp b/SQCSim2021/vertexbuffer.cpp index 4bfb6aa..ff48360 100644 --- a/SQCSim2021/vertexbuffer.cpp +++ b/SQCSim2021/vertexbuffer.cpp @@ -16,10 +16,10 @@ bool VertexBuffer::IsValid() const { return m_isValid; } -std::mutex VertexBuffer::m_opgl; +//std::mutex VertexBuffer::m_opgl; void VertexBuffer::SetMeshData(VertexData* vd, int vertexCount) { - const std::lock_guard prout(VertexBuffer::m_opgl); + //const std::lock_guard prout(VertexBuffer::m_opgl); assert(vertexCount <= USHRT_MAX); if(vertexCount == 0) return; diff --git a/SQCSim2021/vertexbuffer.h b/SQCSim2021/vertexbuffer.h index b835f00..eed8811 100644 --- a/SQCSim2021/vertexbuffer.h +++ b/SQCSim2021/vertexbuffer.h @@ -34,7 +34,7 @@ class VertexBuffer private: - static std::mutex m_opgl; + // static std::mutex m_opgl; bool m_isValid; int m_vertexCount; GLuint m_vertexVboId; diff --git a/SQCSim2021/world.cpp b/SQCSim2021/world.cpp index bd5a337..61c5d51 100644 --- a/SQCSim2021/world.cpp +++ b/SQCSim2021/world.cpp @@ -51,34 +51,42 @@ void World::TransposeWorld(Player& player, Bullet* bullets[MAX_BULLETS]) { if (x > 0) { for (int ax = 0; ax < WORLD_SIZE_X; ++ax) 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.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 (x < 0) { for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax) 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.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)); } if (y > 0) { for (int ax = 0; ax < WORLD_SIZE_X; ++ax) 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.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 (y < 0) { for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax) 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.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)); } @@ -289,14 +297,14 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY int side = 0; int threads = 0; std::future genThList[THREADS_GENERATE_CHUNKS]; - //std::future updateThList[THREADS_UPDATE_CHUNKS]; + std::future updateThList[THREADS_UPDATE_CHUNKS]; if (frameGenerate > 0) --frameGenerate; if (frameUpdate > 0) --frameUpdate; if (frameDelete > 0) --frameDelete; 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 chx = 0; int chy = 0; @@ -370,10 +378,13 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY break; int chx = cx + tx * CHUNK_SIZE_X; 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; + updateThList[threads++] = + 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) { @@ -381,10 +392,13 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY break; int chx = cx + tx * CHUNK_SIZE_X; 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; + updateThList[threads++] = + 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) { @@ -392,10 +406,13 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY break; int chx = cx + tx * CHUNK_SIZE_X; 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; + updateThList[threads++] = + 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) { @@ -403,36 +420,27 @@ void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTY break; int chx = cx + tx * CHUNK_SIZE_X; int chy = cy + ty * CHUNK_SIZE_Z; - 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. + if (ChunkAt(chx, 1, chy) && ChunkAt(chx, 1, chy)->IsDirty()) { updateThList[threads++] = 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; - }*/ + } } if (frameUpdate) break; ++side; } - /*if (threads > 0) { - for (int i = 0; i < threads; ++i) - updateThList[i].wait(); - + if (threads > 0) { for (int i = 0; i < threads; ++i) { - int x, y; + updateThList[i].wait(); Chunk* chunk = updateThList[i].get(); - chunk->GetPosition(x, y); - m_chunks.Set(x - m_center[0], y - m_center[1], chunk); + chunk->FlushMeshToVBO(); } - }*/ + } CleanUpWorld(frameDelete); } \ No newline at end of file