]> git.tdb.fi Git - libs/gl.git/commitdiff
Turn Effect into a Renderable
authorMikko Rasa <tdb@tdb.fi>
Thu, 16 Aug 2012 16:46:12 +0000 (19:46 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 16 Aug 2012 16:46:12 +0000 (19:46 +0300)
They were really intended to be used this way.  This also makes it much
easier to apply an Effect to only a part of a scene.  Previously it would
have been necessary to wrap the Effect in a Pipeline, which doesn't
really support passthrough.

source/effect.cpp [new file with mode: 0644]
source/effect.h
source/pipeline.cpp
source/pipeline.h
source/pipelinepass.h
source/shadowmap.cpp
source/shadowmap.h

diff --git a/source/effect.cpp b/source/effect.cpp
new file mode 100644 (file)
index 0000000..c1be70f
--- /dev/null
@@ -0,0 +1,23 @@
+#include "effect.h"
+
+namespace Msp {
+namespace GL {
+
+Effect::Effect(const Renderable &r):
+       renderable(r)
+{
+       enabled_passes.insert(Tag());
+}
+
+void Effect::enable_for_pass(const Tag &tag)
+{
+       enabled_passes.insert(tag);
+}
+
+void Effect::disable_for_pass(const Tag &tag)
+{
+       enabled_passes.erase(tag);
+}
+
+} // namespace GL
+} // namespace Msp
index f5c740ff5eb0d328a0125b8cb251cab4d4fe43af..dfb369614c28c2388b1dcdd249e20e4d331224ec 100644 (file)
@@ -1,16 +1,28 @@
 #ifndef MSP_GL_EFFECT_H_
 #define MSP_GL_EFFECT_H_
 
+#include <set>
+#include "renderable.h"
+
 namespace Msp {
 namespace GL {
 
-class Effect
+/**
+Effects are used to wrap other renderables and give them additional visual
+properties.
+*/
+class Effect: public Renderable
 {
+protected:
+       const Renderable &renderable;
+       std::set<Tag> enabled_passes;
+
+       Effect(const Renderable &);
 public:
        virtual ~Effect() { }
 
-       virtual void prepare() = 0;
-       virtual void cleanup() = 0;
+       void enable_for_pass(const Tag &);
+       void disable_for_pass(const Tag &);
 };
 
 } // namespace GL
index eca9a49a3c22dfca97cfa5119da4e2d53710ec7a..b9db62d84ef4526945beba95b377bf4ee5afe418 100644 (file)
@@ -1,7 +1,6 @@
 #include <msp/core/maputils.h>
 #include "blend.h"
 #include "camera.h"
-#include "effect.h"
 #include "framebuffer.h"
 #include "lighting.h"
 #include "pipeline.h"
@@ -108,11 +107,6 @@ void Pipeline::remove_renderable(const Renderable &r)
                }
 }
 
-void Pipeline::add_effect(Effect &e)
-{
-       effects.push_back(&e);
-}
-
 void Pipeline::add_postprocessor(PostProcessor &pp)
 {
        postproc.push_back(&pp);
@@ -130,15 +124,9 @@ void Pipeline::render(Renderer &renderer, const Tag &tag) const
        Bind bind_blend(pass.blend);
        Bind bind_lighting(pass.lighting);
 
-       for(vector<Effect *>::const_iterator i=pass.effects.begin(); i!=pass.effects.end(); ++i)
-               (*i)->prepare();
-
        for(vector<Slot>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
                if(i->passes.empty() || i->passes.count(tag))
                        i->renderable->render(renderer, tag);
-
-       for(vector<Effect *>::const_iterator i=pass.effects.end(); i!=pass.effects.begin();)
-               (*--i)->cleanup();
 }
 
 void Pipeline::render_all() const
@@ -153,16 +141,10 @@ void Pipeline::render_all() const
                f->clear(COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT);
        }
 
-       for(vector<Effect *>::const_iterator i=effects.begin(); i!=effects.end(); ++i)
-               (*i)->prepare();
-
        Renderer renderer(camera);
        for(vector<Tag>::const_iterator i=pass_order.begin(); i!=pass_order.end(); ++i)
                render(renderer, *i);
 
-       for(vector<Effect *>::const_iterator i=effects.end(); i!=effects.begin();)
-               (*--i)->cleanup();
-
        if(fbo)
        {
                if(fbo_ms)
index bc793887695b2db51676d979522faf7f680842fc..85179b7d5abfb4c4263c39176b53d6fd26a0a7a5 100644 (file)
@@ -10,7 +10,6 @@ namespace Msp {
 namespace GL {
 
 class Camera;
-class Effect;
 class Framebuffer;
 class PostProcessor;
 class Renderbuffer;
@@ -33,7 +32,6 @@ private:
        std::vector<Tag> pass_order;
        const Camera *camera;
        std::vector<Slot> renderables;
-       std::vector<Effect *> effects;
        std::vector<PostProcessor *> postproc;
        unsigned width;
        unsigned height;
@@ -61,7 +59,6 @@ public:
        void add_renderable(const Renderable &);
        void add_renderable_for_pass(const Renderable &, const Tag &);
        void remove_renderable(const Renderable &);
-       void add_effect(Effect &);
        void add_postprocessor(PostProcessor &);
 
        virtual void render(Renderer &, const Tag &tag = Tag()) const;
index 087e653e5279ec998391b77b9c1f4fabbb088a8b..e996de0c0a61c107500e14482977f277ede1561d 100644 (file)
@@ -1,19 +1,15 @@
 #ifndef MSP_GL_PIPELINEPASS_H_
 #define MSP_GL_PIPELINEPASS_H_
 
-#include <vector>
-
 namespace Msp {
 namespace GL {
 
 class Blend;
 class DepthTest;
-class Effect;
 class Lighting;
 
 struct PipelinePass
 {
-       std::vector<Effect *> effects;
        const Lighting *lighting;
        const DepthTest *depth_test;
        const Blend *blend;
index 11403c6dfb8cb1d48225cd619f01153eec263956..5b2bacad4c4617ad7d617fd333edad7f5232f568 100644 (file)
@@ -3,6 +3,7 @@
 #include "light.h"
 #include "matrix.h"
 #include "misc.h"
+#include "renderer.h"
 #include "scene.h"
 #include "shadowmap.h"
 #include "texunit.h"
@@ -12,9 +13,9 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
-ShadowMap::ShadowMap(unsigned s, const Scene &c, const Light &l):
+ShadowMap::ShadowMap(unsigned s, const Renderable &r, const Light &l):
+       Effect(r),
        size(s),
-       scene(c),
        light(l),
        unit(3),
        radius(1)
@@ -38,8 +39,11 @@ void ShadowMap::set_texture_unit(unsigned u)
        unit = u;
 }
 
-void ShadowMap::prepare()
+void ShadowMap::render(Renderer &renderer, const Tag &tag) const
 {
+       if(!enabled_passes.count(tag))
+               return renderable.render(renderer, tag);
+
        Vector4 lpos = light.get_position();
        if(lpos.w)
        {
@@ -88,6 +92,8 @@ void ShadowMap::prepare()
        matrix[11] = 0;
        matrix[15] = 1;
 
+       renderer.escape();
+
        {
                MatrixStack::Push push_mv(MatrixStack::modelview());
                MatrixStack::Push push_proj(MatrixStack::projection());
@@ -97,7 +103,7 @@ void ShadowMap::prepare()
 
                Bind bind_fbo(fbo, true);
                fbo.clear(DEPTH_BUFFER_BIT);
-               scene.render("shadow");
+               renderable.render("shadow");
        }
 
        depth_buf.bind_to(unit);
@@ -116,10 +122,9 @@ void ShadowMap::prepare()
        enable(GL_TEXTURE_GEN_R);
 
        TexUnit::activate(0);
-}
 
-void ShadowMap::cleanup()
-{
+       renderable.render(renderer, tag);
+
        Texture::unbind_from(unit);
        disable(GL_TEXTURE_GEN_S);
        disable(GL_TEXTURE_GEN_T);
index c44239f2cdb73e7983a117522dc83edbe96119c5..11407462c3e1922c48cd9bb0b3725829e207f595 100644 (file)
@@ -22,16 +22,15 @@ class ShadowMap: public Effect
 {
 private:
        unsigned size;
-       const Scene &scene;
        const Light &light;
-       Framebuffer fbo;
+       mutable Framebuffer fbo;
        unsigned unit;
        Texture2D depth_buf;
        Vector3 target;
        float radius;
 
 public:
-       ShadowMap(unsigned, const Scene &, const Light &);
+       ShadowMap(unsigned, const Renderable &, const Light &);
 
        /** Sets the ShadowMap target point and radius.  The transformation matrix is
        computed so that a sphere with the specified parameters will be completely
@@ -42,8 +41,7 @@ public:
        phase.  The default is texture unit 3. */
        void set_texture_unit(unsigned);
 
-       virtual void prepare();
-       virtual void cleanup();
+       virtual void render(Renderer &, const Tag &) const;
 };
 
 } // namespace GL