--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
#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;
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 });
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;
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();
}
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;
~Renderer();
private:
+ void entity_created(const Game::Events::EntityCreated &);
+ void entity_destroyed(const Game::Events::EntityDestroyed &);
void camera_changed(const Game::Events::CameraChanged &);
public: