2 Commits

3 changed files with 66 additions and 13 deletions

View File

@@ -53,9 +53,11 @@ public:
} }
private: private:
enum class ChunkLoadStyle { RANDOM, CENTER };
using ChunkHashMap = using ChunkHashMap =
tbb::concurrent_unordered_map<ChunkPos, ClientChunk, ChunkPos::Hash>; tbb::concurrent_unordered_map<ChunkPos, ClientChunk, ChunkPos::Hash>;
using ChunkPosSet = std::unordered_set<ChunkPos, ChunkPos::Hash>; using ChunkPosSet = std::unordered_set<ChunkPos, ChunkPos::Hash>;
using ChunkPosVector = std::vector<ChunkPos>;
ClientPlayer m_player; ClientPlayer m_player;
ChunkHashMap m_chunks; ChunkHashMap m_chunks;
std::vector<glm::vec4> m_planes; std::vector<glm::vec4> m_planes;
@@ -64,9 +66,10 @@ private:
mutable std::shared_mutex m_chunks_mutex; mutable std::shared_mutex m_chunks_mutex;
std::mutex m_delete_vbo_mutex; std::mutex m_delete_vbo_mutex;
std::mutex m_delete_vao_mutex; std::mutex m_delete_vao_mutex;
std::mutex m_pending_queue_mutex; std::mutex m_pending_upload_queue_mutex;
std::deque<ClientChunk> m_pending_queue; std::mutex m_pending_chunk_data_queue_mutex;
std::deque<ClientChunk> m_pending_upload_queue;
std::deque<ChunkDataRsp> m_pending_chunk_data_queue;
std::vector<GLuint> m_pending_delete_vbo; std::vector<GLuint> m_pending_delete_vbo;
std::vector<GLuint> m_pending_delete_vao; std::vector<GLuint> m_pending_delete_vao;
std::deque<ChunkPos> m_dirty_queue; std::deque<ChunkPos> m_dirty_queue;
@@ -78,6 +81,7 @@ private:
std::atomic<TickType> m_day_tick{6000}; std::atomic<TickType> m_day_tick{6000};
std::atomic<bool> m_requesting_chunk{false}; std::atomic<bool> m_requesting_chunk{false};
std::shared_ptr<NetworkClient> m_client; std::shared_ptr<NetworkClient> m_client;
ChunkLoadStyle m_chunk_load_style{ChunkLoadStyle::CENTER};
void client_run(std::stop_token token); void client_run(std::stop_token token);
void set_player_pos(); void set_player_pos();

View File

@@ -131,7 +131,7 @@ private:
std::atomic<std::shared_ptr<ThreadPool>> m_gen_thread_pool; std::atomic<std::shared_ptr<ThreadPool>> m_gen_thread_pool;
std::atomic<ChunkLoadStyle> m_chunk_load_style{ChunkLoadStyle::RANDOM}; std::atomic<ChunkLoadStyle> m_chunk_load_style{ChunkLoadStyle::CENTER};
PlayerUUIDMap m_uuid_to_name; PlayerUUIDMap m_uuid_to_name;
tbb::concurrent_unordered_map<std::string, Timer> m_timers; tbb::concurrent_unordered_map<std::string, Timer> m_timers;

View File

@@ -241,6 +241,24 @@ void ClientWorld::client_run(std::stop_token stoken) {
for (auto& x : m_timers) { for (auto& x : m_timers) {
x.second.update(); x.second.update();
} }
// vertex data will genrator in client thread instead of net thread;
std::vector<ChunkDataRsp> temp_data;
{
std::lock_guard lock(m_pending_chunk_data_queue_mutex);
for (auto& x : m_pending_chunk_data_queue) {
temp_data.emplace_back(std::move(x));
}
m_pending_chunk_data_queue.clear();
}
for (auto& x : temp_data) {
ClientChunk chunk{*this};
chunk.receive_chunk(x);
{
std::lock_guard lock(m_pending_upload_queue_mutex);
m_pending_upload_queue.emplace_back(std::move(chunk));
}
}
std::this_thread::sleep_for(milliseconds(DEFAULT_PER_TICK_TIME)); std::this_thread::sleep_for(milliseconds(DEFAULT_PER_TICK_TIME));
} }
} }
@@ -283,7 +301,7 @@ void ClientWorld::request_chunk() {
} }
} }
ChunkPosSet need_send_pos; ChunkPosVector need_send_pos;
{ {
std::lock_guard lk(m_chunks_mutex); std::lock_guard lk(m_chunks_mutex);
for (auto it = m_chunks.begin(); it != m_chunks.end();) { for (auto it = m_chunks.begin(); it != m_chunks.end();) {
@@ -297,13 +315,35 @@ void ClientWorld::request_chunk() {
for (auto pos : required_chunks) { for (auto pos : required_chunks) {
auto it = m_chunks.find(pos); auto it = m_chunks.find(pos);
if (it == m_chunks.end()) { if (it == m_chunks.end()) {
need_send_pos.emplace(pos); need_send_pos.emplace_back(pos);
} }
} }
} }
if (need_send_pos.empty()) { if (need_send_pos.empty()) {
return; return;
} }
using enum ChunkLoadStyle;
switch (m_chunk_load_style) {
case RANDOM:
break;
case CENTER: {
glm::vec3 player_pos = m_player.get_player_pos();
auto dist2 = [player_pos](ChunkPos chunk_pos) {
ChunkPos player_chunk_pos =
get_chunk_pos(player_pos.x, player_pos.z);
float dx = player_chunk_pos.x - chunk_pos.x;
float dz = player_chunk_pos.z - chunk_pos.z;
return dx * dx + dz * dz;
};
std::sort(need_send_pos.begin(), need_send_pos.end(),
[&dist2](const auto& a, const auto& b) {
return dist2(a) < dist2(b);
});
}
}
auto uuid = m_player.get_uuid(); auto uuid = m_player.get_uuid();
ChunkDataReq req; ChunkDataReq req;
for (const auto& pos : need_send_pos) { for (const auto& pos : need_send_pos) {
@@ -317,11 +357,20 @@ void ClientWorld::request_chunk() {
} }
void ClientWorld::receive_chunk(const ChunkDataRsp& data) { void ClientWorld::receive_chunk(const ChunkDataRsp& data) {
ClientChunk chunk{*this};
chunk.receive_chunk(data);
{ {
std::lock_guard lock(m_pending_queue_mutex); std::lock_guard lock(m_chunks_mutex);
m_pending_queue.emplace_back(std::move(chunk)); ChunkPos pos{data.pos().x(), data.pos().z()};
if (m_chunks.find(pos) != m_chunks.end()) {
Logger::warn("Chunk {} {} has already in client world", pos.x,
pos.z);
return;
}
}
{
std::lock_guard lock(m_pending_chunk_data_queue_mutex);
m_pending_chunk_data_queue.emplace_back(std::move(data));
} }
} }
@@ -344,12 +393,12 @@ void ClientWorld::update(float delta_time) {
} }
std::vector<ClientChunk> new_chunks; std::vector<ClientChunk> new_chunks;
{ {
std::lock_guard lock(m_pending_queue_mutex); std::lock_guard lock(m_pending_upload_queue_mutex);
for (auto& c : m_pending_queue) { for (auto& c : m_pending_upload_queue) {
// Logger::info("{} {}", c.get_chunk_pos().x, c.get_chunk_pos().z); // Logger::info("{} {}", c.get_chunk_pos().x, c.get_chunk_pos().z);
new_chunks.emplace_back(std::move(c)); new_chunks.emplace_back(std::move(c));
} }
m_pending_queue.clear(); m_pending_upload_queue.clear();
} }
for (auto& c : new_chunks) { for (auto& c : new_chunks) {
c.upload_to_gpu(); c.upload_to_gpu();