void Presenter::stage_activated(const Game::Events::StageActivated &event)
{
- if(!event.stage.get_system<Renderer>())
- systems.push_back(&event.stage.add_system<Renderer>(ref(gl_view)));
+ if(active_renderer)
+ active_renderer->cancel_output();
+
+ active_renderer = event.stage.get_system<Renderer>();
+ if(!active_renderer)
+ systems.push_back(active_renderer = &event.stage.add_system<Renderer>());
if(event.stage.get_system<Game::Landscape>() && !event.stage.get_system<TerrainMeshCreator>())
systems.push_back(&event.stage.add_system<TerrainMeshCreator>());
+
+ if(active_renderer)
+ active_renderer->output_to_view(gl_view);
}
} // namespace Msp::GameView
namespace Msp::GameView {
-Renderer::Renderer(Game::Stage &s, GL::View &v):
+Renderer::Renderer(Game::Stage &s):
System(s),
- view(v),
event_observer(s.get_event_bus())
{
declare_dependency<Game::Transform>(READ_FRESH);
stage.synthesize_initial_events(event_observer);
content_slot.set(&scene);
- view.set_camera(&gl_camera);
}
Renderer::~Renderer()
entities.clear();
}
+void Renderer::output_to_view(GL::View &v)
+{
+ cancel_output();
+ gl_view = &v;
+ if(active_camera)
+ create_sequence();
+}
+
+void Renderer::cancel_output()
+{
+ if(gl_view)
+ {
+ gl_view->set_content(nullptr);
+ gl_view->set_camera(nullptr);
+ }
+ sequence = nullptr;
+}
+
+void Renderer::create_sequence()
+{
+ unsigned w, h;
+ if(gl_view)
+ {
+ w = gl_view->get_width();
+ h = gl_view->get_height();
+ }
+ else
+ throw invalid_state("Renderer::create_sequence");
+
+ GL::FrameFormat fmt = (GL::COLOR_ATTACHMENT,GL::RGBA8, GL::DEPTH_ATTACHMENT);
+ sequence = make_unique<GL::Sequence>(w, h, fmt);
+ sequence->set_clear_enabled(true);
+ sequence->set_clear_colors({ GL::Color(0.0f) });
+
+ GL::Sequence::Step &opaque = sequence->add_step(GL::Tag(), content_slot);
+ opaque.set_depth_test(GL::LEQUAL);
+ opaque.set_lighting(&lighting);
+
+ unique_ptr<GL::ColorCurve> colorcurve = make_unique<GL::ColorCurve>();
+ colorcurve->set_srgb();
+ sequence->add_postprocessor(*colorcurve);
+ sequence->add_owned(colorcurve.release());
+
+ gl_view->set_content(sequence.get());
+}
+
void Renderer::component_created(const Game::Events::ComponentCreated &event)
{
Game::Handle<Game::MeshSource> mesh_source = dynamic_handle_cast<Game::MeshSource>(event.component);
void Renderer::camera_changed(const Game::Events::CameraChanged &event)
{
active_camera = event.camera;
- if(event.camera)
- {
- GL::FrameFormat fmt = (GL::COLOR_ATTACHMENT,GL::RGBA8, GL::DEPTH_ATTACHMENT);
- sequence = make_unique<GL::Sequence>(view.get_width(), view.get_height(), fmt);
- sequence->set_clear_enabled(true);
- sequence->set_clear_colors({ GL::Color(0.0f) });
-
- GL::Sequence::Step &opaque = sequence->add_step(GL::Tag(), content_slot);
- opaque.set_depth_test(GL::LEQUAL);
- opaque.set_lighting(&lighting);
-
- unique_ptr<GL::ColorCurve> colorcurve = make_unique<GL::ColorCurve>();
- colorcurve->set_srgb();
- sequence->add_postprocessor(*colorcurve);
- sequence->add_owned(colorcurve.release());
-
- view.set_content(sequence.get());
- }
+ if(active_camera && gl_view)
+ create_sequence();
}
void Renderer::tick(Time::TimeDelta)
stage.iterate_objects<MeshRenderer>([](MeshRenderer &m){ m.update_matrix(); });
stage.iterate_objects<LightEmitter>([](LightEmitter &e){ e.update_matrix(); });
- view.render();
+ if(gl_view)
+ gl_view->render();
}
bool operator<(const ShadowedLight &other) const { return shadow_size>other.shadow_size; }
};
- GL::View &view;
Game::EventObserver event_observer;
std::vector<RenderedEntity> entities;
GL::SimpleScene scene;
GL::Slot content_slot;
unsigned shadow_base_size = 4096;
bool shadows_changed = false;
+ GL::View *gl_view = nullptr;
public:
- Renderer(Game::Stage &, GL::View &);
+ Renderer(Game::Stage &);
~Renderer();
+ void output_to_view(GL::View &);
+ void cancel_output();
private:
+ void create_sequence();
+
void component_created(const Game::Events::ComponentCreated &);
RenderedEntity &get_rendered_entity(Game::Handle<Game::Entity>);
void component_destroyed(const Game::Events::ComponentDestroyed &);