]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a new API to Pipeline that ties Renderables and passes together
authorMikko Rasa <tdb@tdb.fi>
Sun, 14 Aug 2016 20:29:49 +0000 (23:29 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 14 Aug 2016 20:29:49 +0000 (23:29 +0300)
The old API is now deprecated and will eventually go away.  There are
two reasons for this change:

1. Pipeline was a sort of pseudo-scene, and in many simple use cases it
was not clear which should be used to hold Renderables.  Scenes are
intended as grouping primitives.

2. It was possible to add multiple passes with the same tag and different
rendering state, but there was no way to add a Renderable for only one of
them.  This led to tags doubling as a way to filter different passes at
the level of individual Renderables.  The intended purpose of tags is to
select between different presentations of a Renderable.

source/pipeline.cpp
source/pipeline.h

index 1833001ff1288fb00257450fe694bd9e44ae62a1..a27058effc08020ed7395645c268249a233b4f9f 100644 (file)
@@ -78,7 +78,7 @@ void Pipeline::set_camera(const Camera *c)
 
 Pipeline::Pass &Pipeline::add_pass(const Tag &tag)
 {
-       passes.push_back(Pass(tag));
+       passes.push_back(Pass(tag, 0));
        return passes.back();
 }
 
@@ -117,6 +117,12 @@ void Pipeline::remove_renderable(const Renderable &r)
                }
 }
 
+Pipeline::Pass &Pipeline::add_pass(const Tag &tag, const Renderable &r)
+{
+       passes.push_back(Pass(tag, &r));
+       return passes.back();
+}
+
 void Pipeline::add_postprocessor(PostProcessor &pp)
 {
        postproc.push_back(&pp);
@@ -134,6 +140,9 @@ void Pipeline::add_postprocessor(PostProcessor &pp)
 void Pipeline::setup_frame() const
 {
        in_frame = true;
+       for(PassList::const_iterator i=passes.begin(); i!=passes.end(); ++i)
+               if(const Renderable *renderable = i->get_renderable())
+                       renderable->setup_frame();
        for(vector<Slot>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
                i->renderable->setup_frame();
 }
@@ -141,6 +150,9 @@ void Pipeline::setup_frame() const
 void Pipeline::finish_frame() const
 {
        in_frame = false;
+       for(PassList::const_iterator i=passes.begin(); i!=passes.end(); ++i)
+               if(const Renderable *renderable = i->get_renderable())
+                       renderable->finish_frame();
        for(vector<Slot>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
                i->renderable->finish_frame();
 }
@@ -180,6 +192,9 @@ void Pipeline::render(Renderer &renderer, const Tag &tag) const
                renderer.set_lighting(i->get_lighting());
                renderer.set_clipping(i->get_clipping());
 
+               if(const Renderable *renderable = i->get_renderable())
+                       renderer.render(*renderable, i->get_tag());
+
                for(vector<Slot>::const_iterator j=renderables.begin(); j!=renderables.end(); ++j)
                        if(j->passes.empty() || j->passes.count(i->get_tag()))
                                renderer.render(*j->renderable, i->get_tag());
@@ -238,12 +253,13 @@ void Pipeline::create_targets(unsigned recreate)
 }
 
 
-Pipeline::Pass::Pass(const Tag &t):
+Pipeline::Pass::Pass(const Tag &t, const Renderable *r):
        tag(t),
        lighting(0),
        depth_test(0),
        blend(0),
-       clipping(0)
+       clipping(0),
+       renderable(r)
 { }
 
 void Pipeline::Pass::set_lighting(const Lighting *l)
index 2c61a53791ae02ce36e3aa8c97cc68fda3b94b95..d07e643176666f861e55dcb75a65f0de28b73021 100644 (file)
@@ -20,25 +20,25 @@ class PostProcessor;
 
 /**
 Encapsulates all of the information used to produce a complete image in the
-framebuffer.  This is the highest level rendering class, combining Renderables
-with a camera, lights and some other influential objects.
+framebuffer.  This is the highest level rendering class.
 
-A Pipeline is also a Renderable itself.  Externally, it only exposes the
-default pass.  Internally, it can hold any number of passes, which are invoked
-in sequence when rendering the default pass is requested.  Each pass can have a
-Lighting, a DepthTest and a Blend to control how it is rendered.
+A Pipeline contains a sequence of passes.  Each pass has a Renderable along
+with Lighting, Clipping, DepthTest and Blend states.  Scenes can be used to
+organize Renderables within a pass.  A Camera can be specified for the entire
+Pipeline.
+
+A Pipeline is also a Renderable itself.  It will only respond to the default
+pass.  The Renderables within the Pipeline will be invoked with whatever tags
+were specified when adding them.
 
 A Pipeline's render method should normally be called without a Renderer; it
 will create one itself, using the camera specified for the Pipeline.  If a
 Renderer is passed, its camera will be used instead.
 
-Renderables are rendered in the order they were added to the Pipeline.  While
-it's possible to remove renderables as well, using a Scene is recommended if
-frequent add/remove operations are needed.
-
-Pipelines may have post-processors to apply full-screen effects. Framebuffer
-objects are automatically used to pass render results to the post-processors.
-High dynamic range and multisample rendering can also be used.
+PostProcessors can be applied after all of the passes in the Pipeline have been
+rendered.  Framebuffer objects are automatically used to pass render results to
+the PostProcessors.  High dynamic range and multisample rendering can be
+requested for increased quality.
 */
 class Pipeline: public Renderable
 {
@@ -51,9 +51,10 @@ public:
                const DepthTest *depth_test;
                const Blend *blend;
                const Clipping *clipping;
+               const Renderable *renderable;
 
        public:
-               Pass(const Tag &);
+               Pass(const Tag &, const Renderable *);
 
                const Tag &get_tag() const { return tag; }
 
@@ -65,6 +66,7 @@ public:
                const DepthTest *get_depth_test() const { return depth_test; }
                const Blend *get_blend() const { return blend; }
                const Clipping *get_clipping() const { return clipping; }
+               const Renderable *get_renderable() const { return renderable; }
        };
 
 private:
@@ -116,11 +118,17 @@ public:
        void set_multisample(unsigned);
        void set_camera(const Camera *);
 
+       // Deprecated
        Pass &add_pass(const Tag &tag);
-
        void add_renderable(const Renderable &);
        void add_renderable_for_pass(const Renderable &, const Tag &);
        void remove_renderable(const Renderable &);
+
+       /** Adds a pass to the pipeline.  It's permissible to add the same
+       Renderable multiple times. */
+       Pass &add_pass(const Tag &, const Renderable &);
+
+       /** Adds a postprocessor to the pipeline. */
        void add_postprocessor(PostProcessor &);
 
        virtual void setup_frame() const;