1 #include <msp/core/maputils.h>
5 #include "framebuffer.h"
8 #include "postprocessor.h"
9 #include "renderbuffer.h"
12 #include "texture2d.h"
19 Pipeline::Pipeline(unsigned w, unsigned h, bool d):
40 void Pipeline::set_hdr(bool h)
47 void Pipeline::set_multisample(unsigned s)
54 void Pipeline::set_camera(const Camera *c)
59 PipelinePass &Pipeline::add_pass(const Tag &tag)
61 PipelinePass &pass = insert_unique(passes, tag, PipelinePass())->second;
62 pass_order.push_back(tag);
66 PipelinePass &Pipeline::get_pass(const Tag &tag)
68 return get_item(passes, tag);
71 const PipelinePass &Pipeline::get_pass(const Tag &tag) const
73 return get_item(passes, tag);
76 void Pipeline::add_renderable(const Renderable &r)
78 for(vector<Slot>::iterator i=renderables.begin(); i!=renderables.end(); ++i)
85 renderables.push_back(&r);
88 void Pipeline::add_renderable_for_pass(const Renderable &r, const Tag &tag)
90 for(vector<Slot>::iterator i=renderables.begin(); i!=renderables.end(); ++i)
93 i->passes.insert(tag);
97 renderables.push_back(&r);
98 renderables.back().passes.insert(tag);
101 void Pipeline::remove_renderable(const Renderable &r)
103 for(vector<Slot>::iterator i=renderables.begin(); i!=renderables.end(); ++i)
104 if(i->renderable==&r)
106 renderables.erase(i);
111 void Pipeline::add_effect(Effect &e)
113 effects.push_back(&e);
116 void Pipeline::add_postprocessor(PostProcessor &pp)
118 postproc.push_back(&pp);
125 void Pipeline::render(Renderer &renderer, const Tag &tag) const
127 const PipelinePass &pass = get_pass(tag);
129 Bind bind_depth_test(pass.depth_test);
130 Bind bind_blend(pass.blend);
131 Bind bind_lighting(pass.lighting);
133 for(vector<Effect *>::const_iterator i=pass.effects.begin(); i!=pass.effects.end(); ++i)
136 for(vector<Slot>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
137 if(i->passes.empty() || i->passes.count(tag))
138 i->renderable->render(renderer, tag);
140 for(vector<Effect *>::const_iterator i=pass.effects.end(); i!=pass.effects.begin();)
144 void Pipeline::render_all() const
151 Framebuffer *f = (fbo_ms ? fbo_ms : fbo);
153 f->clear(COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT);
156 for(vector<Effect *>::const_iterator i=effects.begin(); i!=effects.end(); ++i)
159 Renderer renderer(camera);
160 for(vector<Tag>::const_iterator i=pass_order.begin(); i!=pass_order.end(); ++i)
161 render(renderer, *i);
163 for(vector<Effect *>::const_iterator i=effects.end(); i!=effects.begin();)
169 fbo->blit_from(*fbo_ms, COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT, false);
170 Framebuffer::unbind();
173 // XXX Need two color buffer textures to handle multiple post-processors correctly
174 for(vector<PostProcessor *>::const_iterator i=postproc.begin(); i!=postproc.end(); ++i)
175 (*i)->render(*color_buf, *depth_buf);
178 void Pipeline::create_fbos()
191 fbo = new Framebuffer;
193 color_buf = new Texture2D;
194 color_buf->set_min_filter(NEAREST);
195 color_buf->set_mag_filter(NEAREST);
196 color_buf->set_wrap(CLAMP_TO_EDGE);
197 color_buf->storage((hdr ? RGB16F : RGB), width, height);
198 fbo->attach(COLOR_ATTACHMENT0, *color_buf, 0);
200 depth_buf = new Texture2D;
201 depth_buf->set_min_filter(NEAREST);
202 depth_buf->set_mag_filter(NEAREST);
203 depth_buf->set_wrap(CLAMP_TO_EDGE);
204 depth_buf->storage(DEPTH_COMPONENT, width, height);
205 fbo->attach(DEPTH_ATTACHMENT, *depth_buf, 0);
209 fbo_ms = new Framebuffer;
211 color_buf_ms = new Renderbuffer;
212 color_buf_ms->storage_multisample(samples, (hdr ? RGB16F : RGB), width, height);
213 fbo_ms->attach(COLOR_ATTACHMENT0, *color_buf_ms);
215 depth_buf_ms = new Renderbuffer;
216 depth_buf_ms->storage_multisample(samples, DEPTH_COMPONENT, width, height);
217 fbo_ms->attach(DEPTH_ATTACHMENT, *depth_buf_ms);
222 Pipeline::Slot::Slot(const Renderable *r):