]> git.tdb.fi Git - libs/game.git/commitdiff
Add components for giving entities a visual appearance
authorMikko Rasa <tdb@tdb.fi>
Wed, 2 Nov 2022 22:49:09 +0000 (00:49 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 2 Nov 2022 22:49:09 +0000 (00:49 +0200)
source/game/meshsource.cpp [new file with mode: 0644]
source/game/meshsource.h [new file with mode: 0644]
source/gameview/meshrenderer.cpp [new file with mode: 0644]
source/gameview/meshrenderer.h [new file with mode: 0644]
source/gameview/renderer.cpp
source/gameview/renderer.h

diff --git a/source/game/meshsource.cpp b/source/game/meshsource.cpp
new file mode 100644 (file)
index 0000000..f26fa98
--- /dev/null
@@ -0,0 +1,18 @@
+#include "meshsource.h"
+
+namespace Msp::Game {
+
+DataFile::Loader::ActionMap MeshSourceSetup::Loader::shared_actions;
+
+MeshSourceSetup::Loader::Loader(MeshSourceSetup &s):
+       ObjectLoader<MeshSourceSetup>(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 (file)
index 0000000..74ec781
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef MSP_GAME_MESHSOURCE_H_
+#define MSP_GAME_MESHSOURCE_H_
+
+#include <msp/datafile/objectloader.h>
+#include "component.h"
+
+namespace Msp::Game {
+
+struct MeshSourceSetup
+{
+       class Loader: public DataFile::ObjectLoader<MeshSourceSetup>
+       {
+       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<Entity> 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 (file)
index 0000000..c29aeed
--- /dev/null
@@ -0,0 +1,19 @@
+#include "meshrenderer.h"
+#include <msp/game/entity.h>
+#include <msp/game/transform.h>
+
+namespace Msp::GameView {
+
+MeshRenderer::MeshRenderer(Game::Handle<Game::Entity> e, Game::Handle<Game::MeshSource> s):
+       Component(e),
+       source(s),
+       object(entity->get_stage().get_resources().get<GL::Object>(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 (file)
index 0000000..96fe612
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef MSP_GAMEVIEW_MESHRENDERER_H_
+#define MSP_GAMEVIEW_MESHRENDERER_H_
+
+#include <msp/game/component.h>
+#include <msp/game/meshsource.h>
+#include <msp/gl/objectinstance.h>
+
+namespace Msp::GameView {
+
+class MeshRenderer: public Game::Component
+{
+private:
+       Game::Handle<Game::MeshSource> source;
+       const GL::Object &object;
+       GL::ObjectInstance instance;
+
+public:
+       MeshRenderer(Game::Handle<Game::Entity>, Game::Handle<Game::MeshSource>);
+
+       GL::ObjectInstance &get_instance() { return instance; }
+
+       void update_matrix();
+};
+
+} // namespace Msp::GameView
+
+#endif
index 4bce48420ecd12cca0f48a0dd5d8daaa22a8c4eb..068aa09221a6647021e51df8c3cfb5f6e095c72b 100644 (file)
@@ -1,8 +1,10 @@
 #include "renderer.h"
 #include <msp/game/entity.h>
+#include <msp/game/meshsource.h>
 #include <msp/game/stage.h>
 #include <msp/game/transform.h>
 #include <msp/gl/sequencebuilder.h>
+#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<Game::Events::EntityCreated>([this](auto &e){ entity_created(e); });
+       event_observer.observe<Game::Events::EntityDestroyed>([this](auto &e){ entity_destroyed(e); });
        event_observer.observe<Game::Events::CameraChanged>([this](auto &e){ camera_changed(e); });
 
+       stage.iterate_objects<Game::Entity>([this](auto &e){ entity_created({ Game::Handle<Game::Entity>::from_object(&e) }); });
        if(Game::Handle<Game::Camera> 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<Game::MeshSource> mesh_source = event.entity->get_component<Game::MeshSource>();
+       Game::Handle<MeshRenderer> mesh_renderer = event.entity->get_component<MeshRenderer>();
+       if(mesh_source && !mesh_renderer)
+       {
+               auto i = lower_bound_member(entities, event.entity, &RenderedEntity::entity);
+               i = entities.emplace(i, event.entity, Game::Owned<MeshRenderer>(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();
 }
 
index 4e90a7445f9058ad3539bea4e930a1822c2cd56b..ee0b05c15ab1b70052a4b407820f690a12df9dad 100644 (file)
 
 namespace Msp::GameView {
 
+class MeshRenderer;
+
 class Renderer: public Game::System
 {
 private:
+       struct RenderedEntity
+       {
+               Game::Handle<Game::Entity> entity;
+               Game::Owned<MeshRenderer> mesh_renderer;
+       };
+
        GL::View &view;
        Game::EventObserver event_observer;
+       std::vector<RenderedEntity> entities;
        GL::SimpleScene scene;
        Game::Handle<Game::Camera> 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: