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