mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(entity): add ECS-based entity rendering
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <absl/container/flat_hash_set.h>
|
#include <absl/container/flat_hash_set.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <entt/entt.hpp>
|
||||||
#include <tbb/concurrent_hash_map.h>
|
#include <tbb/concurrent_hash_map.h>
|
||||||
#include <tbb/concurrent_queue.h>
|
#include <tbb/concurrent_queue.h>
|
||||||
#include <tbb/concurrent_unordered_map.h>
|
#include <tbb/concurrent_unordered_map.h>
|
||||||
@@ -46,6 +47,10 @@ struct PlayerRenderData {
|
|||||||
class WorldScene;
|
class WorldScene;
|
||||||
class ClientWorld {
|
class ClientWorld {
|
||||||
public:
|
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(AudioEngine& auido, Config& config, WorldScene& scene);
|
||||||
~ClientWorld();
|
~ClientWorld();
|
||||||
void init(std::string_view player_name,
|
void init(std::string_view player_name,
|
||||||
@@ -110,7 +115,7 @@ public:
|
|||||||
void send_chat_message(ChatMessage& message);
|
void send_chat_message(ChatMessage& message);
|
||||||
void receive_voice_message(VoiceMsg& msg);
|
void receive_voice_message(VoiceMsg& msg);
|
||||||
bool enable_voice_chat() const;
|
bool enable_voice_chat() const;
|
||||||
|
const entt::registry& get_registry();
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
void register_ticktimer(std::string_view id, TickType threshold, Fn&& f) {
|
void register_ticktimer(std::string_view id, TickType threshold, Fn&& f) {
|
||||||
m_ticktimers.emplace(
|
m_ticktimers.emplace(
|
||||||
@@ -147,6 +152,9 @@ private:
|
|||||||
|
|
||||||
static constexpr int WORLD_EXIT_TIMEOUT = 200;
|
static constexpr int WORLD_EXIT_TIMEOUT = 200;
|
||||||
static constexpr int MAX_UPLOAD_CHUNK_SUM = 16;
|
static constexpr int MAX_UPLOAD_CHUNK_SUM = 16;
|
||||||
|
|
||||||
|
entt::registry m_registry;
|
||||||
|
|
||||||
ClientPlayer m_player;
|
ClientPlayer m_player;
|
||||||
OtherPlayerHashMap m_player_info;
|
OtherPlayerHashMap m_player_info;
|
||||||
ChunkHashMap m_chunks;
|
ChunkHashMap m_chunks;
|
||||||
|
|||||||
18
include/Cubed/gameplay/entity.hpp
Normal file
18
include/Cubed/gameplay/entity.hpp
Normal 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
|
||||||
@@ -132,6 +132,7 @@ private:
|
|||||||
|
|
||||||
void render_underwater(ClientWorld& world);
|
void render_underwater(ClientWorld& world);
|
||||||
void render_outline(ClientWorld& world);
|
void render_outline(ClientWorld& world);
|
||||||
|
void render_entity(ClientWorld& world);
|
||||||
void render_player(ClientWorld& world);
|
void render_player(ClientWorld& world);
|
||||||
|
|
||||||
void render_normal_block(const glm::mat4& model_mat,
|
void render_normal_block(const glm::mat4& model_mat,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Cubed/config.hpp"
|
#include "Cubed/config.hpp"
|
||||||
#include "Cubed/gameplay/chunk_generator.hpp"
|
#include "Cubed/gameplay/chunk_generator.hpp"
|
||||||
|
#include "Cubed/gameplay/entity.hpp"
|
||||||
#include "Cubed/gameplay/game_time.hpp"
|
#include "Cubed/gameplay/game_time.hpp"
|
||||||
#include "Cubed/gameplay/packet.hpp"
|
#include "Cubed/gameplay/packet.hpp"
|
||||||
#include "Cubed/scene/world_scene.hpp"
|
#include "Cubed/scene/world_scene.hpp"
|
||||||
@@ -473,6 +474,9 @@ void ClientWorld::init(std::string_view player_name,
|
|||||||
Logger::info("Send Login Request");
|
Logger::info("Send Login Request");
|
||||||
m_client->send(make_packet(req), 0);
|
m_client->send(make_packet(req), 0);
|
||||||
m_audio.play_bgm();
|
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) {
|
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);
|
m_voice_queue.emplace(msg.opus_data(), pos);
|
||||||
}
|
}
|
||||||
bool ClientWorld::enable_voice_chat() const { return m_voice_chat.load(); }
|
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) {
|
void ClientWorld::send_chat_message(ChatMessage& message) {
|
||||||
Arena arena;
|
Arena arena;
|
||||||
auto msg = Arena::Create<ChatMsg>(&arena);
|
auto msg = Arena::Create<ChatMsg>(&arena);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "Cubed/camera.hpp"
|
#include "Cubed/camera.hpp"
|
||||||
#include "Cubed/debug_collector.hpp"
|
#include "Cubed/debug_collector.hpp"
|
||||||
#include "Cubed/gameplay/client_world.hpp"
|
#include "Cubed/gameplay/client_world.hpp"
|
||||||
|
#include "Cubed/gameplay/entity.hpp"
|
||||||
#include "Cubed/render/renderer.hpp"
|
#include "Cubed/render/renderer.hpp"
|
||||||
#include "Cubed/render/renderer_constants.hpp"
|
#include "Cubed/render/renderer_constants.hpp"
|
||||||
#include "Cubed/scene/world_scene.hpp"
|
#include "Cubed/scene/world_scene.hpp"
|
||||||
@@ -46,6 +47,7 @@ void WorldRenderer::render(ClientWorld& world) {
|
|||||||
render_sky(world);
|
render_sky(world);
|
||||||
render_world(world);
|
render_world(world);
|
||||||
render_outline(world);
|
render_outline(world);
|
||||||
|
render_entity(world);
|
||||||
render_player(world);
|
render_player(world);
|
||||||
|
|
||||||
FrameBuffer::unbind();
|
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) {
|
void WorldRenderer::shadow_map_generate(ClientWorld& world) {
|
||||||
float texels_per_unit = 0.0f;
|
float texels_per_unit = 0.0f;
|
||||||
const auto& lightdir = m_parallel_light.lightdir;
|
const auto& lightdir = m_parallel_light.lightdir;
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ void WorldScene::render(Renderer& renderer) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
renderer.render_world(m_client_world);
|
renderer.render_world(m_client_world);
|
||||||
renderer.render_model("model/creature/pig.glb", {0, 100, 0}, m_camera);
|
|
||||||
if (m_show_hud) {
|
if (m_show_hud) {
|
||||||
m_hud_ui.render(renderer);
|
m_hud_ui.render(renderer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user