From 7cbe8cc9893fe14f889321bd55e78b0ed6503e23 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 16 Aug 2012 19:46:12 +0300 Subject: [PATCH] Turn Effect into a Renderable 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 | 23 +++++++++++++++++++++++ source/effect.h | 18 +++++++++++++++--- source/pipeline.cpp | 18 ------------------ source/pipeline.h | 3 --- source/pipelinepass.h | 4 ---- source/shadowmap.cpp | 19 ++++++++++++------- source/shadowmap.h | 8 +++----- 7 files changed, 53 insertions(+), 40 deletions(-) create mode 100644 source/effect.cpp diff --git a/source/effect.cpp b/source/effect.cpp new file mode 100644 index 00000000..c1be70f1 --- /dev/null +++ b/source/effect.cpp @@ -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 diff --git a/source/effect.h b/source/effect.h index f5c740ff..dfb36961 100644 --- a/source/effect.h +++ b/source/effect.h @@ -1,16 +1,28 @@ #ifndef MSP_GL_EFFECT_H_ #define MSP_GL_EFFECT_H_ +#include +#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 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 diff --git a/source/pipeline.cpp b/source/pipeline.cpp index eca9a49a..b9db62d8 100644 --- a/source/pipeline.cpp +++ b/source/pipeline.cpp @@ -1,7 +1,6 @@ #include #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::const_iterator i=pass.effects.begin(); i!=pass.effects.end(); ++i) - (*i)->prepare(); - for(vector::const_iterator i=renderables.begin(); i!=renderables.end(); ++i) if(i->passes.empty() || i->passes.count(tag)) i->renderable->render(renderer, tag); - - for(vector::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::const_iterator i=effects.begin(); i!=effects.end(); ++i) - (*i)->prepare(); - Renderer renderer(camera); for(vector::const_iterator i=pass_order.begin(); i!=pass_order.end(); ++i) render(renderer, *i); - for(vector::const_iterator i=effects.end(); i!=effects.begin();) - (*--i)->cleanup(); - if(fbo) { if(fbo_ms) diff --git a/source/pipeline.h b/source/pipeline.h index bc793887..85179b7d 100644 --- a/source/pipeline.h +++ b/source/pipeline.h @@ -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 pass_order; const Camera *camera; std::vector renderables; - std::vector effects; std::vector 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; diff --git a/source/pipelinepass.h b/source/pipelinepass.h index 087e653e..e996de0c 100644 --- a/source/pipelinepass.h +++ b/source/pipelinepass.h @@ -1,19 +1,15 @@ #ifndef MSP_GL_PIPELINEPASS_H_ #define MSP_GL_PIPELINEPASS_H_ -#include - namespace Msp { namespace GL { class Blend; class DepthTest; -class Effect; class Lighting; struct PipelinePass { - std::vector effects; const Lighting *lighting; const DepthTest *depth_test; const Blend *blend; diff --git a/source/shadowmap.cpp b/source/shadowmap.cpp index 11403c6d..5b2bacad 100644 --- a/source/shadowmap.cpp +++ b/source/shadowmap.cpp @@ -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); diff --git a/source/shadowmap.h b/source/shadowmap.h index c44239f2..11407462 100644 --- a/source/shadowmap.h +++ b/source/shadowmap.h @@ -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 -- 2.45.2