X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Frender%2Frendertarget.cpp;h=00176710c4a796047e02c462e899fde26d0c8ffd;hp=426b2d5257d0ccebb770242f989ef75c45f38283;hb=c8520aa336e92f2eaf9a38c3430c608520a90324;hpb=cd5f37b066352119cf92d53d0001af7ff99be437 diff --git a/source/render/rendertarget.cpp b/source/render/rendertarget.cpp index 426b2d52..00176710 100644 --- a/source/render/rendertarget.cpp +++ b/source/render/rendertarget.cpp @@ -10,146 +10,29 @@ 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 +RenderTarget::RenderTarget(unsigned w, unsigned h, const FrameFormat &f): + width(w), + height(h), + fbo(f) { - 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); - DataType type = get_component_type(f); - unsigned size = 0; - unsigned char out = outputs[count-1]; - if(get_output_type(out)>=get_output_type(RENDER_DEPTH)) + textures.reserve(f.size()); + unsigned samples = f.get_samples(); + for(FrameAttachment a: f) { - if(comp!=DEPTH_COMPONENT) - throw invalid_argument("RenderTargetFormat::operator,"); - switch(type) - { - case UNSIGNED_SHORT: size = 0; break; - case UNSIGNED_INT: size = 2; break; - case FLOAT: size = 3; break; - default: throw invalid_argument("RenderTargetFormat::operator,"); - } - } - else - { - if(comp!=RED && comp!=RG && comp!=RGB && comp!=RGBA) - throw invalid_argument("RenderTargetformat::operator,"); - switch(type) - { - case UNSIGNED_BYTE: size = 0; break; - case HALF_FLOAT: size = 2; break; - case FLOAT: size = 3; break; - default: throw invalid_argument("RenderTargetFormat::operator,"); - } - } - - 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) -{ - 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) - { - 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); + PixelFormat pf = get_attachment_pixelformat(a); - if(samples) + if(samples>1) { Texture2DMultisample *tex2d_ms = new Texture2DMultisample; tex2d_ms->storage(pf, width, height, samples); - fbo.attach(att, *tex2d_ms); + fbo.attach(a, *tex2d_ms); textures.push_back(tex2d_ms); } else { Texture2D *tex2d = new Texture2D; tex2d->storage(pf, width, height, 1); - fbo.attach(att, *tex2d); + fbo.attach(a, *tex2d); textures.push_back(tex2d); } } @@ -157,25 +40,25 @@ void RenderTarget::init(unsigned w, unsigned h, unsigned s, const RenderTargetFo RenderTarget::~RenderTarget() { - for(vector::iterator i=textures.begin(); i!=textures.end(); ++i) - delete *i; + for(Texture *t: textures) + delete t; } const Texture2D &RenderTarget::get_target_texture(unsigned i) const { 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 *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); } @@ -185,17 +68,19 @@ void RenderTarget::set_debug_name(const string &name) #ifdef DEBUG fbo.set_debug_name(name+" [FBO]"); unsigned i = 0; - for(const unsigned char *j=format.begin(); j!=format.end(); ++i, ++j) + for(FrameAttachment a: fbo.get_format()) { - unsigned type = get_output_type(*j); + unsigned attach_pt = get_attach_point(a); string tex_name; - if(type>=get_output_type(RENDER_DEPTH)) + 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, type); + tex_name = Msp::format("%s/color%d", name, attach_pt); - textures[i]->set_debug_name(tex_name+".tex2d"); + textures[i++]->set_debug_name(tex_name+".tex"); } #else (void)name;