#include "renderbuffer.h"
#include "renderer.h"
#include "sequence.h"
-#include "tests.h"
#include "texture2d.h"
#include "view.h"
Sequence::~Sequence()
{
+ for(vector<PostProcStep>::iterator i=postproc.begin(); i!=postproc.end(); ++i)
+ if(i->owned)
+ delete i->postproc;
delete target[0];
delete target[1];
delete target_ms;
void Sequence::add_postprocessor(PostProcessor &pp)
{
- add_postprocessor(&pp, true);
+ add_postprocessor(&pp, false);
}
void Sequence::add_postprocessor_owned(PostProcessor *pp)
{
- add_postprocessor(pp, false);
+ add_postprocessor(pp, true);
}
-void Sequence::add_postprocessor(PostProcessor *pp, bool keep)
+void Sequence::add_postprocessor(PostProcessor *pp, bool owned)
{
- postproc.push_back(pp);
- if(keep)
- postproc.back().keep();
+ postproc.push_back(PostProcStep(pp, owned));
try
{
create_targets(0);
}
catch(...)
{
+ if(!owned)
+ delete pp;
postproc.pop_back();
throw;
}
for(vector<Step>::const_iterator i=steps.begin(); i!=steps.end(); ++i)
if(Renderable *renderable = i->get_renderable())
renderable->setup_frame(renderer);
- for(vector<Slot>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
- i->renderable->setup_frame(renderer);
}
void Sequence::finish_frame()
for(vector<Step>::const_iterator i=steps.begin(); i!=steps.end(); ++i)
if(Renderable *renderable = i->get_renderable())
renderable->finish_frame();
- for(vector<Slot>::const_iterator i=renderables.begin(); i!=renderables.end(); ++i)
- i->renderable->finish_frame();
}
void Sequence::render(Renderer &renderer, Tag tag) const
if(tag.id)
return;
- const Framebuffer *out_fbo = Framebuffer::current();
- // These are no-ops but will ensure the related state gets restored
- BindRestore restore_fbo(out_fbo);
- BindRestore restore_depth_test(DepthTest::current());
- BindRestore restore_blend(Blend::current());
+ Renderer::Push _push(renderer);
+
+ const Framebuffer *out_fbo = renderer.get_framebuffer();
if(target[0])
{
- Framebuffer &fbo = (samples ? target_ms : target[0])->get_framebuffer();
- fbo.bind();
- fbo.clear();
+ renderer.set_framebuffer(&(samples ? target_ms : target[0])->get_framebuffer());
+ renderer.clear();
}
for(vector<Step>::const_iterator i=steps.begin(); i!=steps.end(); ++i)
{
- if(const DepthTest *dt = i->get_depth_test())
- dt->bind();
- else
- DepthTest::unbind();
+ Renderer::Push _push2(renderer);
- if(const Blend *b = i->get_blend())
- b->bind();
- else
- Blend::unbind();
+ renderer.set_depth_test(&i->get_depth_test());
+ renderer.set_stencil_test(&i->get_stencil_test());
+ renderer.set_blend(&i->get_blend());
- renderer.set_lighting(i->get_lighting());
+ if (const Lighting *lighting = i->get_lighting())
+ renderer.add_shader_data(lighting->get_shader_data());
renderer.set_clipping(i->get_clipping());
if(const Renderable *renderable = i->get_renderable())
renderer.render(*renderable, i->get_tag());
-
- for(vector<Slot>::const_iterator j=renderables.begin(); j!=renderables.end(); ++j)
- if(j->passes.empty() || j->passes.count(i->get_tag()))
- renderer.render(*j->renderable, i->get_tag());
}
if(target[0])
{
- DepthTest::unbind();
- Blend::unbind();
-
if(samples)
- target[0]->blit_from(*target_ms);
+ renderer.resolve_multisample(target[0]->get_framebuffer(), COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT);
+
+ renderer.set_depth_test(0);
+ renderer.set_stencil_test(0);
+ renderer.set_blend(0);
for(unsigned i=0; i<postproc.size(); ++i)
{
unsigned j = i%2;
- if(i+1<postproc.size())
- target[1-j]->get_framebuffer().bind();
- else
- out_fbo->bind();
+ renderer.set_framebuffer(i+1<postproc.size() ? &target[1-j]->get_framebuffer() : out_fbo);
const Texture2D &color = target[j]->get_target_texture(RENDER_COLOR);
const Texture2D &depth = target[j]->get_target_texture(RENDER_DEPTH);
- postproc[i]->render(renderer, color, depth);
+ postproc[i].postproc->render(renderer, color, depth);
}
}
}
if(!target_ms && samples)
target_ms = new RenderTarget(width, height, samples, fmt);
+
+#ifdef DEBUG
+ if(!debug_name.empty())
+ set_target_debug_names();
+#endif
+}
+
+void Sequence::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+ debug_name = name;
+ if(!name.empty())
+ set_target_debug_names();
+#else
+ (void)name;
+#endif
+}
+
+void Sequence::set_target_debug_names()
+{
+#ifdef DEBUG
+ for(unsigned i=0; i<2; ++i)
+ if(target[i])
+ target[i]->set_debug_name(format("%s [RT:%d]", debug_name, i));
+ if(target_ms)
+ target_ms->set_debug_name(debug_name+" [RT:ms]");
+#endif
}
Sequence::Step::Step(Tag t, Renderable *r):
tag(t),
lighting(0),
- depth_test(0),
- blend(0),
clipping(0),
renderable(r)
{ }
lighting = l;
}
-void Sequence::Step::set_depth_test(const DepthTest *d)
+void Sequence::Step::set_depth_test(const DepthTest &dt)
+{
+ depth_test = dt;
+}
+
+void Sequence::Step::set_stencil_test(const StencilTest &st)
{
- depth_test = d;
+ stencil_test = st;
}
-void Sequence::Step::set_blend(const Blend *b)
+void Sequence::Step::set_blend(const Blend &b)
{
blend = b;
}
void Sequence::Step::set_clipping(const Clipping *c)
{
- clipping =c;
+ clipping = c;
}
-
-Sequence::Slot::Slot(Renderable *r):
- renderable(r)
-{ }
-
} // namespace GL
} // namespace Msp