X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Frender%2Frendertarget.cpp;h=302b983f478ecd34a1d67ebc92fd3ecec33f7d43;hb=3a1b9cbe2441ae670a97541dc8ccb0a2860c8302;hp=1349944b862ff969f6347d5ca070696bb597f09b;hpb=7aaec9a70b8d7733429bec043f8e33e02956f266;p=libs%2Fgl.git diff --git a/source/render/rendertarget.cpp b/source/render/rendertarget.cpp index 1349944b..302b983f 100644 --- a/source/render/rendertarget.cpp +++ b/source/render/rendertarget.cpp @@ -1,196 +1,92 @@ #include +#include #include "error.h" -#include "renderbuffer.h" #include "rendertarget.h" +#include "texture2d.h" +#include "texture2dmultisample.h" using namespace std; namespace Msp { namespace GL { -RenderTargetFormat::RenderTargetFormat(): - count(0) -{ } - -RenderTargetFormat::RenderTargetFormat(RenderOutput o): - count(1) -{ - outputs[0] = o; -} - -RenderTargetFormat RenderTargetFormat::operator,(RenderOutput o) const -{ - if(count>=MAX_OUTPUTS) - throw invalid_operation("RenderTargetFormat::operator,"); - - RenderTargetFormat result = *this; - result.outputs[result.count++] = o; - - return result; -} - -RenderTargetFormat RenderTargetFormat::operator,(PixelFormat f) const -{ - if(!count) - throw invalid_operation("RenderTargetFormat::operator,"); - - PixelComponents comp = get_components(f); - unsigned size = get_component_size(f); - unsigned char out = outputs[count-1]; - if(get_output_type(out)>=get_output_type(RENDER_DEPTH)) - { - if(comp!=DEPTH_COMPONENT) - throw invalid_argument("RenderTargetFormat::operator,"); - if(size>1) - --size; - if(get_component_type(f)==UNSIGNED_INT) - --size; - } - else - { - if(comp!=RED && comp!=RG && comp!=RGB && comp!=RGBA) - throw invalid_argument("RenderTargetformat::operator,"); - if(size>3) - --size; - } - - out = (out&~15) | (size<<2) | (get_component_count(f)-1); - RenderTargetFormat result = *this; - result.outputs[result.count-1] = out; - - return result; -} - -int RenderTargetFormat::index(RenderOutput o) const -{ - unsigned type = get_output_type(o); - unsigned i = 0; - for(const unsigned char *j=begin(); j!=end(); ++j, ++i) - if(get_output_type(*j)==type) - return i; - return -1; -} - - -PixelFormat get_output_pixelformat(unsigned char o) -{ - PixelComponents comp; - DataType type; - if(get_output_type(o)>=get_output_type(RENDER_DEPTH)) - { - static DataType types[4] = { UNSIGNED_SHORT, UNSIGNED_SHORT, UNSIGNED_INT, FLOAT }; - comp = DEPTH_COMPONENT; - type = types[(o>>2)&3]; - } - else - { - static PixelComponents components[4] = { RED, RG, RGB, RGBA }; - static DataType types[4] = { UNSIGNED_BYTE, UNSIGNED_SHORT, HALF_FLOAT, FLOAT }; - comp = components[o&3]; - type = types[(o>>2)&3]; - } - - return make_pixelformat(comp, type); -} - - -RenderTarget::RenderTarget(unsigned w, unsigned h, RenderOutput o) -{ - init(w, h, 0, o); -} - -RenderTarget::RenderTarget(unsigned w, unsigned h, const RenderTargetFormat &f) +RenderTarget::RenderTarget(unsigned w, unsigned h, const FrameFormat &f): + width(w), + height(h), + fbo(f) { - init(w, h, 0, f); -} - -RenderTarget::RenderTarget(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f) -{ - init(w, h, s, f); -} - -void RenderTarget::init(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f) -{ - width = w; - height = h; - samples = s; - format = f; - - for(const unsigned char *i=format.begin(); i!=format.end(); ++i) + textures.reserve(f.size()); + unsigned samples = f.get_samples(); + for(const uint16_t *i=f.begin(); i!=f.end(); ++i) { - unsigned type = get_output_type(*i); - FramebufferAttachment att; - if(type>=get_output_type(RENDER_DEPTH)) - att = DEPTH_ATTACHMENT; - else - att = static_cast(COLOR_ATTACHMENT0+type); - - PixelFormat pf = get_output_pixelformat(*i); + FrameAttachment fa = static_cast(*i); + PixelFormat pf = get_attachment_pixelformat(*i); - TargetBuffer tgt; - if(samples) + if(samples>1) { - tgt.buffer = new Renderbuffer; - tgt.buffer->storage_multisample(samples, pf, width, height); - fbo.attach(att, *tgt.buffer); + Texture2DMultisample *tex2d_ms = new Texture2DMultisample; + tex2d_ms->storage(pf, width, height, samples); + fbo.attach(fa, *tex2d_ms); + textures.push_back(tex2d_ms); } else { - tgt.texture = new Texture2D; - tgt.texture->storage(pf, width, height, 1); - Sampler &sampler = tgt.texture->get_default_sampler(); - sampler.set_filter(NEAREST); - sampler.set_wrap(CLAMP_TO_EDGE); - fbo.attach(att, *tgt.texture); + Texture2D *tex2d = new Texture2D; + tex2d->storage(pf, width, height, 1); + fbo.attach(fa, *tex2d); + textures.push_back(tex2d); } - buffers.push_back(tgt); } - - fbo.require_complete(); } RenderTarget::~RenderTarget() { - for(vector::iterator i=buffers.begin(); i!=buffers.end(); ++i) - { - if(samples) - delete i->buffer; - else - delete i->texture; - } -} - -void RenderTarget::set_texture_filter(TextureFilter filt) -{ - if(!samples) - { - for(vector::iterator i=buffers.begin(); i!=buffers.end(); ++i) - i->texture->get_default_sampler().set_filter(filt); - } + for(Texture *t: textures) + delete t; } const Texture2D &RenderTarget::get_target_texture(unsigned i) const { - if(i>=buffers.size()) + if(i>=textures.size()) throw out_of_range("RenderTarget::get_target_texture"); - if(samples) + if(fbo.get_format().get_samples()>1) throw invalid_operation("RenderTarget::get_target_texture"); - return *buffers[i].texture; + return *static_cast(textures[i]); } -const Texture2D &RenderTarget::get_target_texture(RenderOutput o) const +const Texture2D &RenderTarget::get_target_texture(FrameAttachment fa) const { - int index = format.index(o); + int index = fbo.get_format().index(fa); if(index<0) - throw key_error(o); + throw key_error(fa); return get_target_texture(index); } -void RenderTarget::blit_from(const RenderTarget &other) +void RenderTarget::set_debug_name(const string &name) { - fbo.blit_from(other.fbo, COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT, false); +#ifdef DEBUG + fbo.set_debug_name(name+" [FBO]"); + const FrameFormat &fmt = fbo.get_format(); + unsigned i = 0; + for(const uint16_t *j=fmt.begin(); j!=fmt.end(); ++i, ++j) + { + unsigned attach_pt = get_attach_point(static_cast(*j)); + + string tex_name; + if(attach_pt==get_attach_point(DEPTH_ATTACHMENT)) + tex_name = name+"/depth"; + else if(attach_pt==get_attach_point(STENCIL_ATTACHMENT)) + tex_name = name+"/stencil"; + else + tex_name = Msp::format("%s/color%d", name, attach_pt); + + textures[i]->set_debug_name(tex_name+".tex2d"); + } +#else + (void)name; +#endif } } // namespace GL