feat(entity): add ECS-based entity rendering

This commit is contained in:
2026-07-25 11:19:27 +08:00
parent 849386a3bc
commit 5951a5e81c
6 changed files with 45 additions and 2 deletions

View File

@@ -14,6 +14,7 @@
#include <absl/container/flat_hash_set.h>
#include <deque>
#include <entt/entt.hpp>
#include <tbb/concurrent_hash_map.h>
#include <tbb/concurrent_queue.h>
#include <tbb/concurrent_unordered_map.h>
@@ -46,6 +47,10 @@ struct PlayerRenderData {
class WorldScene;
class ClientWorld {
public:
ClientWorld(const ClientWorld&) = delete;
ClientWorld(ClientWorld&&) = delete;
ClientWorld& operator=(const ClientWorld&) = delete;
ClientWorld& operator=(ClientWorld&&) = delete;
ClientWorld(AudioEngine& auido, Config& config, WorldScene& scene);
~ClientWorld();
void init(std::string_view player_name,
@@ -110,7 +115,7 @@ public:
void send_chat_message(ChatMessage& message);
void receive_voice_message(VoiceMsg& msg);
bool enable_voice_chat() const;
const entt::registry& get_registry();
template <typename Fn>
void register_ticktimer(std::string_view id, TickType threshold, Fn&& f) {
m_ticktimers.emplace(
@@ -147,6 +152,9 @@ private:
static constexpr int WORLD_EXIT_TIMEOUT = 200;
static constexpr int MAX_UPLOAD_CHUNK_SUM = 16;
entt::registry m_registry;
ClientPlayer m_player;
OtherPlayerHashMap m_player_info;
ChunkHashMap m_chunks;

View File

@@ -0,0 +1,18 @@
#pragma once
#include <glm/glm.hpp>
#include <string>
namespace Cubed {
struct Transform {
glm::vec3 pos;
};
struct Model {
std::string name;
};
struct Health {
float hp = 0;
float max_hp = 20;
};
} // namespace Cubed

View File

@@ -132,6 +132,7 @@ private:
void render_underwater(ClientWorld& world);
void render_outline(ClientWorld& world);
void render_entity(ClientWorld& world);
void render_player(ClientWorld& world);
void render_normal_block(const glm::mat4& model_mat,

View File

@@ -2,6 +2,7 @@
#include "Cubed/config.hpp"
#include "Cubed/gameplay/chunk_generator.hpp"
#include "Cubed/gameplay/entity.hpp"
#include "Cubed/gameplay/game_time.hpp"
#include "Cubed/gameplay/packet.hpp"
#include "Cubed/scene/world_scene.hpp"
@@ -473,6 +474,9 @@ void ClientWorld::init(std::string_view player_name,
Logger::info("Send Login Request");
m_client->send(make_packet(req), 0);
m_audio.play_bgm();
auto pig = m_registry.create();
m_registry.emplace<Transform>(pig, glm::vec3{0.0f, 100.0f, 0.0f});
m_registry.emplace<Model>(pig, "model/creature/pig.glb");
}
void ClientWorld::receive_login_rsp(LoginRsp& rsp) {
@@ -773,6 +777,7 @@ void ClientWorld::receive_voice_message(VoiceMsg& msg) {
m_voice_queue.emplace(msg.opus_data(), pos);
}
bool ClientWorld::enable_voice_chat() const { return m_voice_chat.load(); }
const entt::registry& ClientWorld::get_registry() { return m_registry; }
void ClientWorld::send_chat_message(ChatMessage& message) {
Arena arena;
auto msg = Arena::Create<ChatMsg>(&arena);

View File

@@ -3,6 +3,7 @@
#include "Cubed/camera.hpp"
#include "Cubed/debug_collector.hpp"
#include "Cubed/gameplay/client_world.hpp"
#include "Cubed/gameplay/entity.hpp"
#include "Cubed/render/renderer.hpp"
#include "Cubed/render/renderer_constants.hpp"
#include "Cubed/scene/world_scene.hpp"
@@ -46,6 +47,7 @@ void WorldRenderer::render(ClientWorld& world) {
render_sky(world);
render_world(world);
render_outline(world);
render_entity(world);
render_player(world);
FrameBuffer::unbind();
@@ -290,6 +292,16 @@ void WorldRenderer::render_outline(ClientWorld& world) {
}
}
void WorldRenderer::render_entity(ClientWorld& world) {
auto& registry = world.get_registry();
auto view = registry.view<Transform, Model>();
for (auto entity : view) {
auto [transform, model] = view.get<Transform, Model>(entity);
m_renderer.render_model(model.name, transform.pos,
world.world_scene().camera());
}
}
void WorldRenderer::shadow_map_generate(ClientWorld& world) {
float texels_per_unit = 0.0f;
const auto& lightdir = m_parallel_light.lightdir;

View File

@@ -65,7 +65,6 @@ void WorldScene::render(Renderer& renderer) {
return;
}
renderer.render_world(m_client_world);
renderer.render_model("model/creature/pig.glb", {0, 100, 0}, m_camera);
if (m_show_hud) {
m_hud_ui.render(renderer);
}