From: Mikko Rasa Date: Tue, 27 Jan 2009 19:38:22 +0000 (+0000) Subject: Add a Pipeline framework for constructing complex rendering sequences X-Git-Tag: 1.1~9 X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=e17243fb2421977cb781361828b77718e2cf8d48 Add a Pipeline framework for constructing complex rendering sequences Some minor fixes --- diff --git a/source/bloom.cpp b/source/bloom.cpp index 8a3bf3b2..b9e62698 100644 --- a/source/bloom.cpp +++ b/source/bloom.cpp @@ -51,7 +51,7 @@ static const char combine_fs[]= "varying vec2 texcoord;\n" "void main()\n" "{\n" - " gl_FragColor=mix(texture2D(source, texcoord), texture2D(blurred, texcoord), strength);" + " gl_FragColor=mix(texture2D(source, texcoord), texture2D(blurred, texcoord), strength);\n" "}"; } diff --git a/source/effect.h b/source/effect.h new file mode 100644 index 00000000..9f49c818 --- /dev/null +++ b/source/effect.h @@ -0,0 +1,24 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GL_EFFECT_H_ +#define MSP_GL_EFFECT_H_ + +namespace Msp { +namespace GL { + +class Effect +{ +public: + virtual void prepare() =0; + virtual void cleanup() =0; +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/pipeline.cpp b/source/pipeline.cpp new file mode 100644 index 00000000..fcfead76 --- /dev/null +++ b/source/pipeline.cpp @@ -0,0 +1,134 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "effect.h" +#include "except.h" +#include "framebuffer.h" +#include "lighting.h" +#include "pipeline.h" +#include "postprocessor.h" +#include "renderbuffer.h" +#include "texture2d.h" + +using namespace std; + +namespace Msp { +namespace GL { + +Pipeline::Pipeline(unsigned w, unsigned h, bool d): + width(w), + height(h), + hdr(d), + fbo(0), + color_buf(0), + depth_buf(0) +{ } + +Pipeline::~Pipeline() +{ + delete fbo; + delete color_buf; + delete depth_buf; +} + +PipelinePass &Pipeline::add_pass(const Tag &tag) +{ + if(passes.count(tag.id)) + throw KeyError("Pass already exists"); + + PipelinePass &pass=passes[tag.id]; + pass_order.push_back(tag); + return pass; +} + +PipelinePass &Pipeline::get_pass(const Tag &tag) +{ + map::iterator i=passes.find(tag.id); + if(i==passes.end()) + throw KeyError("Unknown pass"); + return i->second; +} + +const PipelinePass &Pipeline::get_pass(const Tag &tag) const +{ + map::const_iterator i=passes.find(tag.id); + if(i==passes.end()) + throw KeyError("Unknown pass"); + return i->second; +} + +bool Pipeline::has_pass(const Tag &tag) const +{ + return passes.count(tag.id); +} + +void Pipeline::add_renderable(const Renderable &r) +{ + renderables.push_back(&r); +} + +void Pipeline::add_effect(Effect &e) +{ + effects.push_back(&e); +} + +void Pipeline::add_postprocessor(PostProcessor &pp) +{ + postproc.push_back(&pp); + if(!fbo) + { + fbo=new Framebuffer; + color_buf=new Texture2D; + color_buf->set_min_filter(NEAREST); + color_buf->set_mag_filter(NEAREST); + color_buf->storage((hdr ? RGB16F : RGB), width, height, 0); + color_buf->image(0, RGB, UNSIGNED_BYTE, 0); + fbo->attach(COLOR_ATTACHMENT0, *color_buf, 0); + depth_buf=new Renderbuffer; + depth_buf->storage(DEPTH_COMPONENT, width, height); + fbo->attach(DEPTH_ATTACHMENT, *depth_buf); + Framebuffer::unbind(); + } +} + +void Pipeline::render(const Tag &tag) const +{ + const PipelinePass &pass=get_pass(tag); + if(pass.lighting) + pass.lighting->bind(); + 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) + (*i)->render(tag); + for(vector::const_iterator i=pass.effects.end(); i--!=pass.effects.begin();) + (*i)->cleanup(); + if(pass.lighting) + Lighting::unbind(); +} + +void Pipeline::render_all() const +{ + if(fbo) + { + fbo->bind(); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + } + for(vector::const_iterator i=effects.begin(); i!=effects.end(); ++i) + (*i)->prepare(); + for(vector::const_iterator i=pass_order.begin(); i!=pass_order.end(); ++i) + render(*i); + for(vector::const_iterator i=effects.end(); i--!=effects.begin();) + (*i)->cleanup(); + if(fbo) + Framebuffer::unbind(); + // XXX Need two color buffer textures to handle multiple post-processors correctly + for(vector::const_iterator i=postproc.begin(); i!=postproc.end(); ++i) + (*i)->render(*color_buf); +} + +} // namespace GL +} // namespace Msp diff --git a/source/pipeline.h b/source/pipeline.h new file mode 100644 index 00000000..19bea10a --- /dev/null +++ b/source/pipeline.h @@ -0,0 +1,59 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GL_PIPELINE_H_ +#define MSP_GL_PIPELINE_H_ + +#include +#include "pipelinepass.h" +#include "renderable.h" + +namespace Msp { +namespace GL { + +class Effect; +class Framebuffer; +class PostProcessor; +class Renderbuffer; +class Texture2D; + +class Pipeline: public Renderable +{ +private: + std::map passes; + std::vector pass_order; + std::vector renderables; + std::vector effects; + std::vector postproc; + unsigned width; + unsigned height; + bool hdr; + Framebuffer *fbo; + Texture2D *color_buf; + Renderbuffer *depth_buf; + +public: + Pipeline(unsigned, unsigned, bool); + ~Pipeline(); + + PipelinePass &add_pass(const Tag &tag); + PipelinePass &get_pass(const Tag &tag); + const PipelinePass &get_pass(const Tag &tag) const; + virtual bool has_pass(const Tag &tag) const; + + void add_renderable(const Renderable &); + void add_effect(Effect &); + void add_postprocessor(PostProcessor &); + + virtual void render(const Tag &tag=Tag()) const; + void render_all() const; +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/pipelinepass.cpp b/source/pipelinepass.cpp new file mode 100644 index 00000000..e49db7e2 --- /dev/null +++ b/source/pipelinepass.cpp @@ -0,0 +1,18 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "pipelinepass.h" + +namespace Msp { +namespace GL { + +PipelinePass::PipelinePass(): + lighting(0) +{ } + +} // namespace GL +} // namespace Msp diff --git a/source/pipelinepass.h b/source/pipelinepass.h new file mode 100644 index 00000000..9f797729 --- /dev/null +++ b/source/pipelinepass.h @@ -0,0 +1,30 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GL_PIPELINEPASS_H_ +#define MSP_GL_PIPELINEPASS_H_ + +#include + +namespace Msp { +namespace GL { + +class Effect; +class Lighting; + +struct PipelinePass +{ + std::vector effects; + Lighting *lighting; + + PipelinePass(); +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/pixelformat.h b/source/pixelformat.h index ef373b86..6063145a 100644 --- a/source/pixelformat.h +++ b/source/pixelformat.h @@ -40,7 +40,7 @@ enum PixelFormat LUMINANCE16F = GL_LUMINANCE16F_ARB, LUMINANCE32F = GL_LUMINANCE32F_ARB, LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA, - LUMINANCE_ALPHA8 = GL_LUMINANCE_ALPHA8, + LUMINANCE_ALPHA8 = GL_LUMINANCE8_ALPHA8, LUMINANCE_ALPHA16F = GL_LUMINANCE_ALPHA16F_ARB, LUMINANCE_ALPHA32F = GL_LUMINANCE_ALPHA32F_ARB, };