]> git.tdb.fi Git - libs/gl.git/blobdiff - source/render/rendertarget.cpp
Change various generated texture names to use the unified extension
[libs/gl.git] / source / render / rendertarget.cpp
index 7bdac6703e3554e60162a90839139c1f4efba4f3..00176710c4a796047e02c462e899fde26d0c8ffd 100644 (file)
 #include <msp/core/maputils.h>
 #include <msp/strings/format.h>
 #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
+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 pf = get_attachment_pixelformat(a);
 
-
-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<FramebufferAttachment>(COLOR_ATTACHMENT0+type);
-
-               PixelFormat pf = get_output_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(a, *tex2d_ms);
+                       textures.push_back(tex2d_ms);
                }
                else
                {
-                       tgt.texture = new Texture2D;
-                       tgt.texture->storage(pf, width, height, 1);
-                       fbo.attach(att, *tgt.texture);
+                       Texture2D *tex2d = new Texture2D;
+                       tex2d->storage(pf, width, height, 1);
+                       fbo.attach(a, *tex2d);
+                       textures.push_back(tex2d);
                }
-               buffers.push_back(tgt);
        }
-
-       fbo.require_complete();
 }
 
 RenderTarget::~RenderTarget()
 {
-       for(vector<TargetBuffer>::iterator i=buffers.begin(); i!=buffers.end(); ++i)
-       {
-               if(samples)
-                       delete i->buffer;
-               else
-                       delete i->texture;
-       }
+       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<const Texture2D *>(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)
-{
-       fbo.blit_from(other.fbo, COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT, false);
-}
-
 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 buf_name;
-               if(type>=get_output_type(RENDER_DEPTH))
-                       buf_name = name+"/depth";
+               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
-                       buf_name = Msp::format("%s/color%d", name, type);
+                       tex_name = Msp::format("%s/color%d", name, attach_pt);
 
-               if(samples)
-                       buffers[i].buffer->set_debug_name(buf_name+".tex2d");
-               else
-                       buffers[i].texture->set_debug_name(buf_name+".rbuf");
+               textures[i++]->set_debug_name(tex_name+".tex");
        }
 #else
        (void)name;