]> git.tdb.fi Git - libs/game.git/blob - source/gameview/renderer.cpp
068aa09221a6647021e51df8c3cfb5f6e095c72b
[libs/game.git] / source / gameview / renderer.cpp
1 #include "renderer.h"
2 #include <msp/game/entity.h>
3 #include <msp/game/meshsource.h>
4 #include <msp/game/stage.h>
5 #include <msp/game/transform.h>
6 #include <msp/gl/sequencebuilder.h>
7 #include "meshrenderer.h"
8
9 using namespace std;
10
11 namespace Msp::GameView {
12
13 Renderer::Renderer(Game::Stage &s, GL::View &v):
14         System(s),
15         view(v),
16         event_observer(s.get_event_bus())
17 {
18         event_observer.observe<Game::Events::EntityCreated>([this](auto &e){ entity_created(e); });
19         event_observer.observe<Game::Events::EntityDestroyed>([this](auto &e){ entity_destroyed(e); });
20         event_observer.observe<Game::Events::CameraChanged>([this](auto &e){ camera_changed(e); });
21
22         stage.iterate_objects<Game::Entity>([this](auto &e){ entity_created({ Game::Handle<Game::Entity>::from_object(&e) }); });
23         if(Game::Handle<Game::Camera> ac = stage.get_active_camera())
24                 camera_changed({ ac });
25
26         view.set_camera(&gl_camera);
27 }
28
29 Renderer::~Renderer()
30 { }
31
32 void Renderer::entity_created(const Game::Events::EntityCreated &event)
33 {
34         Game::Handle<Game::MeshSource> mesh_source = event.entity->get_component<Game::MeshSource>();
35         Game::Handle<MeshRenderer> mesh_renderer = event.entity->get_component<MeshRenderer>();
36         if(mesh_source && !mesh_renderer)
37         {
38                 auto i = lower_bound_member(entities, event.entity, &RenderedEntity::entity);
39                 i = entities.emplace(i, event.entity, Game::Owned<MeshRenderer>(event.entity, mesh_source));
40                 scene.add(i->mesh_renderer->get_instance());
41         }
42 }
43
44 void Renderer::entity_destroyed(const Game::Events::EntityDestroyed &event)
45 {
46         auto i = lower_bound_member(entities, event.entity, &RenderedEntity::entity);
47         if(i!=entities.end() && i->entity==event.entity)
48         {
49                 scene.remove(i->mesh_renderer->get_instance());
50                 entities.erase(i);
51         }
52 }
53
54 void Renderer::camera_changed(const Game::Events::CameraChanged &event)
55 {
56         active_camera = event.camera;
57         if(event.camera)
58         {
59                 const string &seq_name = event.camera->get_sequence_name();
60                 if(seq_name!=current_seq_name)
61                 {
62                         current_seq_name = seq_name;
63                         GL::SequenceBuilder bld(stage.get_resources().get<GL::SequenceTemplate>(seq_name));
64                         bld.set_renderable("content", scene);
65                         sequence.reset(bld.build(view));
66                         view.set_content(sequence.get());
67                 }
68         }
69 }
70
71 void Renderer::tick(Time::TimeDelta)
72 {
73         if(active_camera)
74         {
75                 Game::Handle<Game::Transform> transform = active_camera->get_entity()->get_transform();
76                 if(transform)
77                         gl_camera.set_object_matrix(transform->get_world_matrix());
78                 else
79                         gl_camera.set_object_matrix(GL::Matrix());
80                 if(active_camera->is_orthographic())
81                 {
82                         const LinAl::Vector<float, 2> &size = active_camera->get_size();
83                         gl_camera.set_orthographic(size.x, size.y);
84                 }
85                 else
86                         gl_camera.set_field_of_view(active_camera->get_fov_vertical());
87                 gl_camera.set_depth_clip(active_camera->get_near_clip(), active_camera->get_far_clip());
88         }
89
90         for(const RenderedEntity &e: entities)
91                 e.mesh_renderer->update_matrix();
92
93         view.render();
94 }
95
96 } // namespace Msp::GameView