From: Mikko Rasa Date: Mon, 20 Aug 2012 13:13:46 +0000 (+0300) Subject: Simplify Pipeline pass management X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=5eb4e7ebd0dc36bc0d9817dedcc152f3bd581f70;p=libs%2Fgl.git Simplify Pipeline pass management Originally I planned to use Pipelines to bundle objects with effects like environmentally mapped reflection. However, that task was delegated to effects themselves recently, so there's no longer need for passthrough rendering in Pipeline. The render_all function was also a nuisance, as it required Pipelines to be treated differently from other Renderables. Passes are now stored in a list instead of a map. This allows multiple passes with the same tag (think multipass lighting), and avoids the need to store the pass order separately. --- diff --git a/source/pipeline.cpp b/source/pipeline.cpp index ce155970..67ddf656 100644 --- a/source/pipeline.cpp +++ b/source/pipeline.cpp @@ -60,19 +60,8 @@ void Pipeline::set_camera(const Camera *c) Pipeline::Pass &Pipeline::add_pass(const Tag &tag) { - Pass &pass = insert_unique(passes, tag, Pass())->second; - pass_order.push_back(tag); - return pass; -} - -Pipeline::Pass &Pipeline::get_pass(const Tag &tag) -{ - return get_item(passes, tag); -} - -const Pipeline::Pass &Pipeline::get_pass(const Tag &tag) const -{ - return get_item(passes, tag); + passes.push_back(Pass(tag)); + return passes.back(); } void Pipeline::add_renderable(const Renderable &r) @@ -119,34 +108,38 @@ void Pipeline::add_postprocessor(PostProcessor &pp) } } -void Pipeline::render(Renderer &renderer, const Tag &tag) const +void Pipeline::render(const Tag &tag) const { - const Pass &pass = get_pass(tag); + if(tag.id) + return; - Bind bind_depth_test(pass.get_depth_test()); - Bind bind_blend(pass.get_blend()); - Bind bind_lighting(pass.get_lighting()); - - for(vector::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) - if(i->passes.empty() || i->passes.count(tag)) - i->renderable->render(renderer, tag); + Renderer renderer(camera); + render(renderer, tag); } -void Pipeline::render_all() const +void Pipeline::render(Renderer &renderer, const Tag &tag) const { - if(camera) - camera->apply(); + if(tag.id) + return; if(fbo) { Framebuffer *f = (fbo_ms ? fbo_ms : fbo); + // XXX exception safety f->bind(); f->clear(COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT); } - Renderer renderer(camera); - for(vector::const_iterator i=pass_order.begin(); i!=pass_order.end(); ++i) - render(renderer, *i); + for(PassList::const_iterator i=passes.begin(); i!=passes.end(); ++i) + { + Bind bind_depth_test(i->get_depth_test()); + Bind bind_blend(i->get_blend()); + Bind bind_lighting(i->get_lighting()); + + for(vector::const_iterator j=renderables.begin(); j!=renderables.end(); ++j) + if(j->passes.empty() || j->passes.count(i->get_tag())) + j->renderable->render(renderer, i->get_tag()); + } if(fbo) { @@ -204,7 +197,8 @@ void Pipeline::create_fbos() } -Pipeline::Pass::Pass(): +Pipeline::Pass::Pass(const Tag &t): + tag(t), lighting(0), depth_test(0), blend(0) diff --git a/source/pipeline.h b/source/pipeline.h index 011a96bb..c14245fa 100644 --- a/source/pipeline.h +++ b/source/pipeline.h @@ -23,12 +23,15 @@ public: class Pass { private: + Tag tag; const Lighting *lighting; const DepthTest *depth_test; const Blend *blend; public: - Pass(); + Pass(const Tag &); + + const Tag &get_tag() const { return tag; } void set_lighting(const Lighting *); void set_depth_test(const DepthTest *); @@ -47,10 +50,9 @@ private: Slot(const Renderable *); }; - typedef std::map PassMap; + typedef std::list PassList; - PassMap passes; - std::vector pass_order; + PassList passes; const Camera *camera; std::vector renderables; std::vector postproc; @@ -74,16 +76,14 @@ public: void set_camera(const Camera *); Pass &add_pass(const Tag &tag); - Pass &get_pass(const Tag &tag); - const Pass &get_pass(const Tag &tag) const; void add_renderable(const Renderable &); void add_renderable_for_pass(const Renderable &, const Tag &); void remove_renderable(const Renderable &); void add_postprocessor(PostProcessor &); + virtual void render(const Tag &tag = Tag()) const; virtual void render(Renderer &, const Tag &tag = Tag()) const; - void render_all() const; private: void create_fbos();