mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(multiplayer): add rendering of other players as colored cubes
This commit is contained in:
@@ -190,13 +190,23 @@ void ClientWorld::receive_time(const UpdateTime& rsp) {
|
||||
m_day_tick = rsp.day_tick();
|
||||
}
|
||||
|
||||
void ClientWorld::receive_other_player(const PlayerInfoRsp& rsp) {
|
||||
{
|
||||
std::lock_guard lock(m_other_players_mutex);
|
||||
m_other_players[rsp.uuid()].name = rsp.name();
|
||||
m_other_players[rsp.uuid()].pos =
|
||||
glm::vec3{rsp.pos().x(), rsp.pos().y(), rsp.pos().z()};
|
||||
// Logger::info("Player {} pos Update", rsp.name());
|
||||
}
|
||||
}
|
||||
|
||||
void ClientWorld::init(std::string_view player_name,
|
||||
std::shared_ptr<NetworkClient> client) {
|
||||
m_chunks.reserve(MAX_DISTANCE * MAX_DISTANCE * 4);
|
||||
m_player.init(player_name);
|
||||
m_client = client;
|
||||
// timer
|
||||
register_timer("player_pos", 2, [this]() { report_player_pos(); });
|
||||
register_timer("player_pos", 1, [this]() { report_player_pos(); });
|
||||
LoginReq req;
|
||||
req.set_name(m_player.get_name());
|
||||
while (!client->is_connected()) {
|
||||
@@ -450,6 +460,13 @@ void ClientWorld::update(float delta_time) {
|
||||
}
|
||||
}
|
||||
}
|
||||
m_render_player_data.clear();
|
||||
{
|
||||
std::lock_guard lock(m_other_players_mutex);
|
||||
for (auto& [uuid, player] : m_other_players) {
|
||||
m_render_player_data.emplace_back(player.name, player.pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 ClientWorld::sunlight_dir() const {
|
||||
@@ -476,8 +493,11 @@ int ClientWorld::rendering_distance() const {
|
||||
void ClientWorld::rendering_distance(int rendering_distance) {
|
||||
m_rendering_distance = rendering_distance;
|
||||
}
|
||||
std::vector<ChunkRenderSnapshot>& ClientWorld::render_snapshots() {
|
||||
const std::vector<ChunkRenderSnapshot>& ClientWorld::render_snapshots() const {
|
||||
return m_render_snapshots;
|
||||
};
|
||||
const std::vector<RenderPlayerData>& ClientWorld::render_player_data() const {
|
||||
return m_render_player_data;
|
||||
}
|
||||
std::vector<glm::vec4>& ClientWorld::planes() { return m_planes; }
|
||||
} // namespace Cubed
|
||||
@@ -81,8 +81,8 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
||||
} break;
|
||||
case to_num(PacketEnum::CHUNK_DATA_RSP): {
|
||||
ChunkDataRsp rsp;
|
||||
Logger::info("Client: Receive Chunk Data rsp, size {}mb",
|
||||
body_data.size() / 1024.0f / 1024);
|
||||
// Logger::info("Client: Receive Chunk Data rsp, size {}mb",
|
||||
// body_data.size() / 1024.0f / 1024);
|
||||
if (rsp.ParseFromArray(body_data.data(), body_data.size())) {
|
||||
m_world.receive_chunk(rsp);
|
||||
}
|
||||
@@ -100,6 +100,12 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
||||
m_world.receive_time(rsp);
|
||||
}
|
||||
}
|
||||
case to_num(PacketEnum::PLAYER_INFO_RSP): {
|
||||
PlayerInfoRsp rsp;
|
||||
if (rsp.ParseFromArray(body_data.data(), body_data.size())) {
|
||||
m_world.receive_other_player(rsp);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} catch (const asio::system_error& e) {
|
||||
|
||||
@@ -400,13 +400,40 @@ void ServerWorld::update() {
|
||||
|
||||
void ServerWorld::sync_player_pos(const std::string& uuid, float x, float y,
|
||||
float z) {
|
||||
std::lock_guard lock(m_player_mutex);
|
||||
auto it = m_players.find(uuid);
|
||||
if (it == m_players.end()) {
|
||||
Logger::warn("Player {} is not in this Server", uuid);
|
||||
return;
|
||||
std::string name;
|
||||
{
|
||||
std::lock_guard lock(m_player_mutex);
|
||||
auto it = m_players.find(uuid);
|
||||
if (it == m_players.end()) {
|
||||
Logger::warn("Player {} is not in this Server", uuid);
|
||||
return;
|
||||
}
|
||||
it->second.update_pos(x, y, z);
|
||||
name = it->second.get_name();
|
||||
}
|
||||
|
||||
// update other player pos;
|
||||
std::vector<std::shared_ptr<Session>> other;
|
||||
{
|
||||
std::shared_lock lock(m_player_mutex);
|
||||
for (auto& [o_uuid, player] : m_players) {
|
||||
if (o_uuid == uuid) {
|
||||
continue;
|
||||
}
|
||||
other.emplace_back(player.get_session());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& session : other) {
|
||||
PlayerInfoRsp rsp;
|
||||
rsp.set_uuid(uuid);
|
||||
rsp.set_name(name);
|
||||
auto* pos = rsp.mutable_pos();
|
||||
pos->set_x(x);
|
||||
pos->set_y(y);
|
||||
pos->set_z(z);
|
||||
session->send(make_packet(rsp));
|
||||
}
|
||||
it->second.update_pos(x, y, z);
|
||||
}
|
||||
|
||||
void ServerWorld::handle_player_login(const std::string& name,
|
||||
|
||||
@@ -77,7 +77,7 @@ asio::awaitable<void> Session::read_loop() {
|
||||
}
|
||||
if (cmd_id == to_num(PacketEnum::CHUNK_DATA_REQ)) {
|
||||
ChunkDataReq req;
|
||||
Logger::info("Session: Receive Chunk Data req");
|
||||
// Logger::info("Session: Receive Chunk Data req");
|
||||
if (req.ParseFromArray(body_data.data(), body_data.size())) {
|
||||
m_server_world.handle_chunk_req(
|
||||
req.uuid(), ChunkPos(req.pos().x(), req.pos().z()));
|
||||
|
||||
@@ -5,4 +5,10 @@ import "common/vector3.proto";
|
||||
message PlayerPos {
|
||||
string uuid = 1;
|
||||
Vec3 pos = 2;
|
||||
}
|
||||
|
||||
message PlayerInfoRsp {
|
||||
string uuid = 1;
|
||||
string name = 2;
|
||||
Vec3 pos = 3;
|
||||
}
|
||||
@@ -34,6 +34,7 @@ Renderer::~Renderer() {
|
||||
glDeleteBuffers(1, &m_sky_vbo);
|
||||
glDeleteBuffers(1, &m_ui_vbo);
|
||||
glDeleteBuffers(1, &m_text_vbo);
|
||||
glDeleteBuffers(1, &m_player_vbo);
|
||||
glBindVertexArray(0);
|
||||
glDeleteVertexArrays(NUM_VAO, m_vao.data());
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
@@ -88,7 +89,9 @@ void Renderer::init() {
|
||||
"shaders/billboard_f_shader.glsl"};
|
||||
Shader water_shader{"water", "shaders/water_v_shader.glsl",
|
||||
"shaders/water_f_shader.glsl"};
|
||||
|
||||
Shader player_shader{"player", "shaders/player_v_shader.glsl",
|
||||
"shaders/player_f_shader.glsl"};
|
||||
m_shaders.insert({player_shader.hash(), std::move(player_shader)});
|
||||
m_shaders.insert({world_shader.hash(), std::move(world_shader)});
|
||||
m_shaders.insert({outline_shader.hash(), std::move(outline_shader)});
|
||||
m_shaders.insert({sky_shdaer.hash(), std::move(sky_shdaer)});
|
||||
@@ -102,6 +105,7 @@ void Renderer::init() {
|
||||
m_shaders.insert({depth_shader.hash(), std::move(depth_shader)});
|
||||
m_shaders.insert({billboard.hash(), std::move(billboard)});
|
||||
m_shaders.insert({water_shader.hash(), std::move(water_shader)});
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
@@ -167,6 +171,15 @@ void Renderer::init() {
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glBindVertexArray(m_vao[5]);
|
||||
glGenBuffers(1, &m_player_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_player_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES_PLAYER), VERTICES_PLAYER,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
init_quad();
|
||||
init_text();
|
||||
hot_reload();
|
||||
@@ -217,7 +230,7 @@ void Renderer::render() {
|
||||
render_sky();
|
||||
render_world();
|
||||
render_outline();
|
||||
|
||||
render_player();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
@@ -927,6 +940,26 @@ void Renderer::render_world() {
|
||||
DebugCollector::get().report(
|
||||
"rendered_chunk", "Rendered Chunk: " + std::to_string(rendered_sum));
|
||||
}
|
||||
|
||||
void Renderer::render_player() {
|
||||
auto& shader = get_shader("player");
|
||||
shader.use();
|
||||
m_v_mat = m_camera.get_camera_lookat();
|
||||
|
||||
auto& players = m_world.render_player_data();
|
||||
|
||||
for (auto& player : players) {
|
||||
m_m_mat = glm::translate(glm::mat4(1.0f),
|
||||
player.pos + glm::vec3(-0.5f, 0.0f, -0.5f));
|
||||
m_mv_mat = m_v_mat * m_m_mat;
|
||||
shader.set_loc("mv_matrix", m_mv_mat);
|
||||
shader.set_loc("proj_matrix", m_p_mat);
|
||||
glBindVertexArray(m_vao[5]);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
void Renderer::render_dev_panel() {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
Reference in New Issue
Block a user