From 11b6e88d0dc492e868508c0f3cc6ebd8aa2706e4 Mon Sep 17 00:00:00 2001 From: zhenyan121 <3367366583@qq.com> Date: Sat, 18 Apr 2026 12:35:48 +0800 Subject: [PATCH] feat: initialize world in multiple threads --- CMakeLists.txt | 4 +++ include/Cubed/gameplay/chunk.hpp | 2 +- src/gameplay/chunk.cpp | 2 +- src/gameplay/world.cpp | 42 ++++++++++++++++++++++++++++---- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b0f96e..ae8a7e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,6 +137,10 @@ target_link_libraries(${PROJECT_NAME} Freetype::Freetype ) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_link_libraries(${PROJECT_NAME} PRIVATE tbb) +endif() + if (UNIX AND NOT APPLE) target_link_libraries(${PROJECT_NAME} PRIVATE diff --git a/include/Cubed/gameplay/chunk.hpp b/include/Cubed/gameplay/chunk.hpp index 2b43331..b98320f 100644 --- a/include/Cubed/gameplay/chunk.hpp +++ b/include/Cubed/gameplay/chunk.hpp @@ -54,7 +54,7 @@ public: // 1 : (-1, 0) // 2 : (0, 1) // 3 : (0, -1) - void gen_vertex_data(const std::vector*>& neighbor_block); + void gen_vertex_data(const std::array*, 4>& neighbor_block); void upload_to_gpu(); GLuint get_vbo() const; diff --git a/src/gameplay/chunk.cpp b/src/gameplay/chunk.cpp index 8e2ea6e..393d111 100644 --- a/src/gameplay/chunk.cpp +++ b/src/gameplay/chunk.cpp @@ -66,7 +66,7 @@ int Chunk::get_index(const glm::vec3& pos) { return Chunk::get_index(pos.x, pos.y, pos.z); } -void Chunk::gen_vertex_data(const std::vector*>& neighbor_block) { +void Chunk::gen_vertex_data(const std::array*, 4>& neighbor_block) { m_vertexs_data.clear(); static const glm::ivec3 DIR[6] = { diff --git a/src/gameplay/world.cpp b/src/gameplay/world.cpp index e3de6e0..dc7deb5 100644 --- a/src/gameplay/world.cpp +++ b/src/gameplay/world.cpp @@ -7,12 +7,18 @@ #include #include +#include #include static constexpr ChunkPos CHUNK_DIR[] { {1, 0}, {-1, 0}, {0, 1}, {0, -1} }; +struct ChunkRenderData { + std::array*, 4> neighbor_block; + Chunk* chunk; +}; + World::World() { } @@ -66,7 +72,6 @@ Player& World::get_player(const std::string& name){ return it->second; } - void World::init_world() { auto t1 = std::chrono::system_clock::now(); for (int s = 0; s < DISTANCE; s++) { @@ -79,14 +84,16 @@ void World::init_world() { m_chunks.emplace(pos, Chunk(*this, pos)); } } - + /* for (auto& chunk_map : m_chunks) { auto& [chunk_pos, chunk] = chunk_map; chunk.init_chunk(); } // After block gen fininshed - std::vector*> neighbor_block(4); + + std::array*, 4> neighbor_block; + for (auto& [pos, chunk] : m_chunks) { for (int i = 0; i < 4; i++) { auto it = m_chunks.find(pos + CHUNK_DIR[i]); @@ -98,6 +105,31 @@ void World::init_world() { } chunk.gen_vertex_data(neighbor_block); } + */ + std::for_each(std::execution::par, m_chunks.begin(), m_chunks.end(), [](auto& chunk_map){ + auto& [chunk_pos, chunk] = chunk_map; + chunk.init_chunk(); + }); + std::vector pending_gen_data; + for (auto& [pos, chunk] : m_chunks) { + ChunkRenderData data; + data.chunk = &chunk; + for (int i = 0; i < 4; i++) { + auto it = m_chunks.find(pos + CHUNK_DIR[i]); + if (it != m_chunks.end()) { + data.neighbor_block[i] = &(it->second.get_chunk_blocks()); + } else { + data.neighbor_block[i] = nullptr; + } + } + pending_gen_data.emplace_back(std::move(data)); + } + std::for_each(std::execution::par, pending_gen_data.begin(), pending_gen_data.end(), [](ChunkRenderData& data){ + if(!data.chunk) { + return ; + } + data.chunk->gen_vertex_data(data.neighbor_block); + }); for (auto& chunk_map : m_chunks) { auto& [chunk_pos, chunk] = chunk_map; chunk.upload_to_gpu(); @@ -221,7 +253,7 @@ void World::gen_chunks_internal() { } } - std::vector*> neighbor_block(4); + std::array*, 4> neighbor_block; for (auto& [pos, chunk] : new_chunks) { @@ -427,7 +459,7 @@ void World::update(float delta_time) { for (auto& [pos, chunk] : m_chunks) { if (chunk.is_dirty()) { // the curial fator influence - std::vector*> neighbor_block(4); + std::array*, 4> neighbor_block; for (int i = 0; i < 4; i++) { auto it = m_chunks.find(pos + CHUNK_DIR[i]); if (it != m_chunks.end()) {