feat: initialize world in multiple threads

This commit is contained in:
2026-04-18 12:35:48 +08:00
parent 099b1cbdd7
commit 11b6e88d0d
4 changed files with 43 additions and 7 deletions

View File

@@ -137,6 +137,10 @@ target_link_libraries(${PROJECT_NAME}
Freetype::Freetype 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) if (UNIX AND NOT APPLE)
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
PRIVATE PRIVATE

View File

@@ -54,7 +54,7 @@ public:
// 1 : (-1, 0) // 1 : (-1, 0)
// 2 : (0, 1) // 2 : (0, 1)
// 3 : (0, -1) // 3 : (0, -1)
void gen_vertex_data(const std::vector<const std::vector<uint8_t>*>& neighbor_block); void gen_vertex_data(const std::array<const std::vector<uint8_t>*, 4>& neighbor_block);
void upload_to_gpu(); void upload_to_gpu();
GLuint get_vbo() const; GLuint get_vbo() const;

View File

@@ -66,7 +66,7 @@ int Chunk::get_index(const glm::vec3& pos) {
return Chunk::get_index(pos.x, pos.y, pos.z); return Chunk::get_index(pos.x, pos.y, pos.z);
} }
void Chunk::gen_vertex_data(const std::vector<const std::vector<uint8_t>*>& neighbor_block) { void Chunk::gen_vertex_data(const std::array<const std::vector<uint8_t>*, 4>& neighbor_block) {
m_vertexs_data.clear(); m_vertexs_data.clear();
static const glm::ivec3 DIR[6] = { static const glm::ivec3 DIR[6] = {

View File

@@ -7,12 +7,18 @@
#include <Cubed/tools/cubed_hash.hpp> #include <Cubed/tools/cubed_hash.hpp>
#include <Cubed/tools/math_tools.hpp> #include <Cubed/tools/math_tools.hpp>
#include <execution>
#include <unordered_set> #include <unordered_set>
static constexpr ChunkPos CHUNK_DIR[] { static constexpr ChunkPos CHUNK_DIR[] {
{1, 0}, {-1, 0}, {0, 1}, {0, -1} {1, 0}, {-1, 0}, {0, 1}, {0, -1}
}; };
struct ChunkRenderData {
std::array<const std::vector<uint8_t>*, 4> neighbor_block;
Chunk* chunk;
};
World::World() { World::World() {
} }
@@ -66,7 +72,6 @@ Player& World::get_player(const std::string& name){
return it->second; return it->second;
} }
void World::init_world() { void World::init_world() {
auto t1 = std::chrono::system_clock::now(); auto t1 = std::chrono::system_clock::now();
for (int s = 0; s < DISTANCE; s++) { for (int s = 0; s < DISTANCE; s++) {
@@ -79,14 +84,16 @@ void World::init_world() {
m_chunks.emplace(pos, Chunk(*this, pos)); m_chunks.emplace(pos, Chunk(*this, pos));
} }
} }
/*
for (auto& chunk_map : m_chunks) { for (auto& chunk_map : m_chunks) {
auto& [chunk_pos, chunk] = chunk_map; auto& [chunk_pos, chunk] = chunk_map;
chunk.init_chunk(); chunk.init_chunk();
} }
// After block gen fininshed // After block gen fininshed
std::vector<const std::vector<uint8_t>*> neighbor_block(4);
std::array<const std::vector<uint8_t>*, 4> neighbor_block;
for (auto& [pos, chunk] : m_chunks) { for (auto& [pos, chunk] : m_chunks) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
auto it = m_chunks.find(pos + CHUNK_DIR[i]); auto it = m_chunks.find(pos + CHUNK_DIR[i]);
@@ -98,6 +105,31 @@ void World::init_world() {
} }
chunk.gen_vertex_data(neighbor_block); 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<ChunkRenderData> 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) { for (auto& chunk_map : m_chunks) {
auto& [chunk_pos, chunk] = chunk_map; auto& [chunk_pos, chunk] = chunk_map;
chunk.upload_to_gpu(); chunk.upload_to_gpu();
@@ -221,7 +253,7 @@ void World::gen_chunks_internal() {
} }
} }
std::vector<const std::vector<uint8_t>*> neighbor_block(4); std::array<const std::vector<uint8_t>*, 4> neighbor_block;
for (auto& [pos, chunk] : new_chunks) { for (auto& [pos, chunk] : new_chunks) {
@@ -427,7 +459,7 @@ void World::update(float delta_time) {
for (auto& [pos, chunk] : m_chunks) { for (auto& [pos, chunk] : m_chunks) {
if (chunk.is_dirty()) { if (chunk.is_dirty()) {
// the curial fator influence // the curial fator influence
std::vector<const std::vector<uint8_t>*> neighbor_block(4); std::array<const std::vector<uint8_t>*, 4> neighbor_block;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
auto it = m_chunks.find(pos + CHUNK_DIR[i]); auto it = m_chunks.find(pos + CHUNK_DIR[i]);
if (it != m_chunks.end()) { if (it != m_chunks.end()) {