1 #include <msp/core/maputils.h>
4 #include "framebuffer.h"
7 #include "postprocessor.h"
8 #include "renderbuffer.h"
11 #include "texture2d.h"
18 Pipeline::Pipeline(unsigned w, unsigned h, bool d):
39 void Pipeline::set_hdr(bool h)
46 void Pipeline::set_multisample(unsigned s)
53 void Pipeline::set_camera(const Camera *c)
58 PipelinePass &Pipeline::add_pass(const Tag &tag)
60 PipelinePass &pass = insert_unique(passes, tag, PipelinePass())->second;
61 pass_order.push_back(tag);
65 PipelinePass &Pipeline::get_pass(const Tag &tag)
67 return get_item(passes, tag);
70 const PipelinePass &Pipeline::get_pass(const Tag &tag) const
72 return get_item(passes, tag);
75 void Pipeline::add_renderable(const Renderable &r)
77 for(vector<Slot>::iterator i=renderables.begin(); i!=renderables.end(); ++i)
84 renderables.push_back(&r);
87 void Pipeline::add_renderable_for_pass(const Renderable &r, const Tag &tag)
89 for(vector<Slot>::iterator i=renderables.begin(); i!=renderables.end(); ++i)
92 i->passes.insert(tag);
96 renderables.push_back(&r);
97 renderables.back().passes.insert(tag);
100 void Pipeline::remove_renderable(const Renderable &r)
102 for(vector<Slot>::iterator i=renderables.begin(); i!=renderables.end(); ++i)
103 if(i->renderable==&r)
105 renderables.erase(i);
110 void Pipeline::add_postprocessor(PostProcessor &pp)
112 postproc.push_back(&pp);
119 void Pipeline::render(Renderer &renderer, const Tag &tag) const
121 const PipelinePass &pass = get_pass(tag);
123 Bind bind_depth_test(pass.depth_test);
124 Bind bind_blend(pass.blend);
125 Bind bind_lighting(pass.lighting);
127 for(vector<Slot>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
128 if(i->passes.empty() || i->passes.count(tag))
129 i->renderable->render(renderer, tag);
132 void Pipeline::render_all() const
139 Framebuffer *f = (fbo_ms ? fbo_ms : fbo);
141 f->clear(COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT);
144 Renderer renderer(camera);
145 for(vector<Tag>::const_iterator i=pass_order.begin(); i!=pass_order.end(); ++i)
146 render(renderer, *i);
151 fbo->blit_from(*fbo_ms, COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT, false);
152 Framebuffer::unbind();
155 // XXX Need two color buffer textures to handle multiple post-processors correctly
156 for(vector<PostProcessor *>::const_iterator i=postproc.begin(); i!=postproc.end(); ++i)
157 (*i)->render(*color_buf, *depth_buf);
160 void Pipeline::create_fbos()
173 fbo = new Framebuffer;
175 color_buf = new Texture2D;
176 color_buf->set_min_filter(NEAREST);
177 color_buf->set_mag_filter(NEAREST);
178 color_buf->set_wrap(CLAMP_TO_EDGE);
179 color_buf->storage((hdr ? RGB16F : RGB), width, height);
180 fbo->attach(COLOR_ATTACHMENT0, *color_buf, 0);
182 depth_buf = new Texture2D;
183 depth_buf->set_min_filter(NEAREST);
184 depth_buf->set_mag_filter(NEAREST);
185 depth_buf->set_wrap(CLAMP_TO_EDGE);
186 depth_buf->storage(DEPTH_COMPONENT, width, height);
187 fbo->attach(DEPTH_ATTACHMENT, *depth_buf, 0);
191 fbo_ms = new Framebuffer;
193 color_buf_ms = new Renderbuffer;
194 color_buf_ms->storage_multisample(samples, (hdr ? RGB16F : RGB), width, height);
195 fbo_ms->attach(COLOR_ATTACHMENT0, *color_buf_ms);
197 depth_buf_ms = new Renderbuffer;
198 depth_buf_ms->storage_multisample(samples, DEPTH_COMPONENT, width, height);
199 fbo_ms->attach(DEPTH_ATTACHMENT, *depth_buf_ms);
204 Pipeline::Slot::Slot(const Renderable *r):