]> git.tdb.fi Git - libs/game.git/commitdiff
Further refactor Renderer and MeshRenderer
authorMikko Rasa <tdb@tdb.fi>
Sat, 28 Jan 2023 12:38:59 +0000 (14:38 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sat, 28 Jan 2023 13:56:54 +0000 (15:56 +0200)
The ObjectInstance is now hidden inside MeshRenderer and RAII is used to
remove it from the scene.  This limits the instance to being in only a
single scene, but I don't think that will be an issue.

source/gameview/meshrenderer.cpp
source/gameview/meshrenderer.h
source/gameview/renderer.cpp
source/gameview/renderer.h

index 34fd6a73276605b110f18dbeb6cd990000dc850d..872ecce1acf5305ddfb8d87bc00230bb572ec239 100644 (file)
@@ -10,6 +10,21 @@ MeshRenderer::MeshRenderer(Game::Handle<Game::Entity> e, const GL::Object &o):
        instance(object)
 { }
 
+MeshRenderer::~MeshRenderer()
+{
+       if(scene)
+               scene->remove(instance);
+}
+
+void MeshRenderer::set_scene(GL::Scene *s)
+{
+       if(scene)
+               scene->remove(instance);
+       scene = s;
+       if(scene)
+               scene->add(instance);
+}
+
 void MeshRenderer::update_matrix()
 {
        instance.set_matrix(entity->get_transform()->get_world_matrix());
index 2bed53f7bb98193f8f19b292be8c6d741f4d65f0..15c82553f094f2204c240d48f99b874b5437dae3 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <msp/game/component.h>
 #include <msp/gl/objectinstance.h>
+#include <msp/gl/scene.h>
 #include "mspgameview_api.h"
 
 namespace Msp::GameView {
@@ -12,11 +13,13 @@ class MSPGAMEVIEW_API MeshRenderer: public Game::Component
 private:
        const GL::Object &object;
        GL::ObjectInstance instance;
+       GL::Scene *scene = nullptr;
 
 public:
        MeshRenderer(Game::Handle<Game::Entity>, const GL::Object &);
+       ~MeshRenderer();
 
-       GL::ObjectInstance &get_instance() { return instance; }
+       void set_scene(GL::Scene *);
 
        void update_matrix();
 };
index 35f9c6fbb7ceead3050b879ccaadcf7630431857..a12333392108b42f8a00b380065abdf353d46d30 100644 (file)
@@ -30,32 +30,40 @@ Renderer::Renderer(Game::Stage &s, GL::View &v):
 }
 
 Renderer::~Renderer()
-{ }
+{
+       /* Ensure that the MeshRenderers and LightEmitters are destroyed before the
+       scene and lighting */
+       entities.clear();
+}
 
 void Renderer::component_created(const Game::Events::ComponentCreated &event)
 {
        Game::Handle<Game::MeshSource> mesh_source = dynamic_handle_cast<Game::MeshSource>(event.component);
        if(mesh_source)
        {
-               Game::Handle<Game::Entity> entity = mesh_source->get_entity();
-               if(!entity->get_component<MeshRenderer>())
+               RenderedEntity &re = get_rendered_entity(event.component->get_entity());
+               if(!re.mesh_renderer)
                {
-                       auto i = lower_bound_member(entities, entity, &RenderedEntity::entity);
                        const GL::Object &object = stage.get_resources().get<GL::Object>(mesh_source->get_object_name());
-                       i = entities.emplace(i, entity, Game::Owned<MeshRenderer>(entity, object));
-                       scene.add(i->mesh_renderer->get_instance());
+                       re.mesh_renderer = Game::Owned<MeshRenderer>(re.entity, object);
+                       re.mesh_renderer->set_scene(&scene);
                }
        }
 }
 
+Renderer::RenderedEntity &Renderer::get_rendered_entity(Game::Handle<Game::Entity> entity)
+{
+       auto i = lower_bound_member(entities, entity, &RenderedEntity::entity);
+       if(i!=entities.end() && i->entity==entity)
+               return *i;
+       return *entities.emplace(i, entity);
+}
+
 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)
@@ -100,4 +108,9 @@ void Renderer::tick(Time::TimeDelta)
        view.render();
 }
 
+
+Renderer::RenderedEntity::RenderedEntity(Game::Handle<Game::Entity> e):
+       entity(e)
+{ }
+
 } // namespace Msp::GameView
index f3691586eb068b8a9fd3edc6778ec4445ece4bfc..484e07cb650c6494185c0fb02dd6c9abd95a56af 100644 (file)
@@ -23,6 +23,8 @@ private:
        {
                Game::Handle<Game::Entity> entity;
                Game::Owned<MeshRenderer> mesh_renderer;
+
+               RenderedEntity(Game::Handle<Game::Entity>);
        };
 
        GL::View &view;
@@ -40,6 +42,7 @@ public:
 
 private:
        void component_created(const Game::Events::ComponentCreated &);
+       RenderedEntity &get_rendered_entity(Game::Handle<Game::Entity>);
        void entity_destroyed(const Game::Events::EntityDestroyed &);
        void camera_changed(const Game::Events::CameraChanged &);