--- /dev/null
+#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
#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
#include <msp/core/maputils.h>
#include "blend.h"
#include "camera.h"
-#include "effect.h"
#include "framebuffer.h"
#include "lighting.h"
#include "pipeline.h"
}
}
-void Pipeline::add_effect(Effect &e)
-{
- effects.push_back(&e);
-}
-
void Pipeline::add_postprocessor(PostProcessor &pp)
{
postproc.push_back(&pp);
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
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)
namespace GL {
class Camera;
-class Effect;
class Framebuffer;
class PostProcessor;
class Renderbuffer;
std::vector<Tag> pass_order;
const Camera *camera;
std::vector<Slot> renderables;
- std::vector<Effect *> effects;
std::vector<PostProcessor *> postproc;
unsigned width;
unsigned height;
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;
#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;
#include "light.h"
#include "matrix.h"
#include "misc.h"
+#include "renderer.h"
#include "scene.h"
#include "shadowmap.h"
#include "texunit.h"
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)
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)
{
matrix[11] = 0;
matrix[15] = 1;
+ renderer.escape();
+
{
MatrixStack::Push push_mv(MatrixStack::modelview());
MatrixStack::Push push_proj(MatrixStack::projection());
Bind bind_fbo(fbo, true);
fbo.clear(DEPTH_BUFFER_BIT);
- scene.render("shadow");
+ renderable.render("shadow");
}
depth_buf.bind_to(unit);
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);
{
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
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