From 76d859d1429782901799c9886f833cd331b670ce Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 3 Nov 2022 00:49:09 +0200 Subject: [PATCH] Add components for giving entities a visual appearance --- source/game/meshsource.cpp | 18 ++++++++++++++ source/game/meshsource.h | 42 ++++++++++++++++++++++++++++++++ source/gameview/meshrenderer.cpp | 19 +++++++++++++++ source/gameview/meshrenderer.h | 27 ++++++++++++++++++++ source/gameview/renderer.cpp | 31 +++++++++++++++++++++++ source/gameview/renderer.h | 11 +++++++++ 6 files changed, 148 insertions(+) create mode 100644 source/game/meshsource.cpp create mode 100644 source/game/meshsource.h create mode 100644 source/gameview/meshrenderer.cpp create mode 100644 source/gameview/meshrenderer.h diff --git a/source/game/meshsource.cpp b/source/game/meshsource.cpp new file mode 100644 index 0000000..f26fa98 --- /dev/null +++ b/source/game/meshsource.cpp @@ -0,0 +1,18 @@ +#include "meshsource.h" + +namespace Msp::Game { + +DataFile::Loader::ActionMap MeshSourceSetup::Loader::shared_actions; + +MeshSourceSetup::Loader::Loader(MeshSourceSetup &s): + ObjectLoader(s) +{ + set_actions(shared_actions); +} + +void MeshSourceSetup::Loader::init_actions() +{ + add("object", &MeshSourceSetup::object_name); +} + +} // namespace Msp::Game diff --git a/source/game/meshsource.h b/source/game/meshsource.h new file mode 100644 index 0000000..74ec781 --- /dev/null +++ b/source/game/meshsource.h @@ -0,0 +1,42 @@ +#ifndef MSP_GAME_MESHSOURCE_H_ +#define MSP_GAME_MESHSOURCE_H_ + +#include +#include "component.h" + +namespace Msp::Game { + +struct MeshSourceSetup +{ + class Loader: public DataFile::ObjectLoader + { + private: + static Loader::ActionMap shared_actions; + + public: + Loader(MeshSourceSetup &); + + protected: + void init_actions() override; + }; + + std::string object_name; +}; + +class MeshSource: public Component +{ +public: + using Setup = MeshSourceSetup; + +private: + const Setup &setup; + +public: + MeshSource(Handle e, const Setup &s): Component(e), setup(s) { } + + const std::string &get_object_name() const { return setup.object_name; } +}; + +} // namespace Msp::Game + +#endif diff --git a/source/gameview/meshrenderer.cpp b/source/gameview/meshrenderer.cpp new file mode 100644 index 0000000..c29aeed --- /dev/null +++ b/source/gameview/meshrenderer.cpp @@ -0,0 +1,19 @@ +#include "meshrenderer.h" +#include +#include + +namespace Msp::GameView { + +MeshRenderer::MeshRenderer(Game::Handle e, Game::Handle s): + Component(e), + source(s), + object(entity->get_stage().get_resources().get(source->get_object_name())), + instance(object) +{ } + +void MeshRenderer::update_matrix() +{ + instance.set_matrix(entity->get_transform()->get_world_matrix()); +} + +} // namespace Msp::GameView diff --git a/source/gameview/meshrenderer.h b/source/gameview/meshrenderer.h new file mode 100644 index 0000000..96fe612 --- /dev/null +++ b/source/gameview/meshrenderer.h @@ -0,0 +1,27 @@ +#ifndef MSP_GAMEVIEW_MESHRENDERER_H_ +#define MSP_GAMEVIEW_MESHRENDERER_H_ + +#include +#include +#include + +namespace Msp::GameView { + +class MeshRenderer: public Game::Component +{ +private: + Game::Handle source; + const GL::Object &object; + GL::ObjectInstance instance; + +public: + MeshRenderer(Game::Handle, Game::Handle); + + GL::ObjectInstance &get_instance() { return instance; } + + void update_matrix(); +}; + +} // namespace Msp::GameView + +#endif diff --git a/source/gameview/renderer.cpp b/source/gameview/renderer.cpp index 4bce484..068aa09 100644 --- a/source/gameview/renderer.cpp +++ b/source/gameview/renderer.cpp @@ -1,8 +1,10 @@ #include "renderer.h" #include +#include #include #include #include +#include "meshrenderer.h" using namespace std; @@ -13,8 +15,11 @@ Renderer::Renderer(Game::Stage &s, GL::View &v): view(v), event_observer(s.get_event_bus()) { + event_observer.observe([this](auto &e){ entity_created(e); }); + event_observer.observe([this](auto &e){ entity_destroyed(e); }); event_observer.observe([this](auto &e){ camera_changed(e); }); + stage.iterate_objects([this](auto &e){ entity_created({ Game::Handle::from_object(&e) }); }); if(Game::Handle ac = stage.get_active_camera()) camera_changed({ ac }); @@ -24,6 +29,28 @@ Renderer::Renderer(Game::Stage &s, GL::View &v): Renderer::~Renderer() { } +void Renderer::entity_created(const Game::Events::EntityCreated &event) +{ + Game::Handle mesh_source = event.entity->get_component(); + Game::Handle mesh_renderer = event.entity->get_component(); + if(mesh_source && !mesh_renderer) + { + auto i = lower_bound_member(entities, event.entity, &RenderedEntity::entity); + i = entities.emplace(i, event.entity, Game::Owned(event.entity, mesh_source)); + scene.add(i->mesh_renderer->get_instance()); + } +} + +void Renderer::entity_destroyed(const Game::Events::EntityDestroyed &event) +{ + auto i = lower_bound_member(entities, event.entity, &RenderedEntity::entity); + if(i!=entities.end() && i->entity==event.entity) + { + scene.remove(i->mesh_renderer->get_instance()); + entities.erase(i); + } +} + void Renderer::camera_changed(const Game::Events::CameraChanged &event) { active_camera = event.camera; @@ -59,6 +86,10 @@ void Renderer::tick(Time::TimeDelta) gl_camera.set_field_of_view(active_camera->get_fov_vertical()); gl_camera.set_depth_clip(active_camera->get_near_clip(), active_camera->get_far_clip()); } + + for(const RenderedEntity &e: entities) + e.mesh_renderer->update_matrix(); + view.render(); } diff --git a/source/gameview/renderer.h b/source/gameview/renderer.h index 4e90a74..ee0b05c 100644 --- a/source/gameview/renderer.h +++ b/source/gameview/renderer.h @@ -13,11 +13,20 @@ namespace Msp::GameView { +class MeshRenderer; + class Renderer: public Game::System { private: + struct RenderedEntity + { + Game::Handle entity; + Game::Owned mesh_renderer; + }; + GL::View &view; Game::EventObserver event_observer; + std::vector entities; GL::SimpleScene scene; Game::Handle active_camera; GL::Camera gl_camera; @@ -29,6 +38,8 @@ public: ~Renderer(); private: + void entity_created(const Game::Events::EntityCreated &); + void entity_destroyed(const Game::Events::EntityDestroyed &); void camera_changed(const Game::Events::CameraChanged &); public: -- 2.43.0