1 #include <msp/core/maputils.h>
2 #include <msp/strings/format.h>
4 #include "renderbuffer.h"
5 #include "rendertarget.h"
12 RenderTargetFormat::RenderTargetFormat():
16 RenderTargetFormat::RenderTargetFormat(RenderOutput o):
22 RenderTargetFormat RenderTargetFormat::operator,(RenderOutput o) const
24 if(count>=MAX_OUTPUTS)
25 throw invalid_operation("RenderTargetFormat::operator,");
27 RenderTargetFormat result = *this;
28 result.outputs[result.count++] = o;
33 RenderTargetFormat RenderTargetFormat::operator,(PixelFormat f) const
36 throw invalid_operation("RenderTargetFormat::operator,");
38 PixelComponents comp = get_components(f);
39 DataType type = get_component_type(f);
41 unsigned char out = outputs[count-1];
42 if(get_output_type(out)>=get_output_type(RENDER_DEPTH))
44 if(comp!=DEPTH_COMPONENT)
45 throw invalid_argument("RenderTargetFormat::operator,");
48 case UNSIGNED_SHORT: size = 0; break;
49 case UNSIGNED_INT: size = 2; break;
50 case FLOAT: size = 3; break;
51 default: throw invalid_argument("RenderTargetFormat::operator,");
56 if(comp!=RED && comp!=RG && comp!=RGB && comp!=RGBA)
57 throw invalid_argument("RenderTargetformat::operator,");
60 case UNSIGNED_BYTE: size = 0; break;
61 case HALF_FLOAT: size = 2; break;
62 case FLOAT: size = 3; break;
63 default: throw invalid_argument("RenderTargetFormat::operator,");
67 out = (out&~15) | (size<<2) | (get_component_count(f)-1);
68 RenderTargetFormat result = *this;
69 result.outputs[result.count-1] = out;
74 int RenderTargetFormat::index(RenderOutput o) const
76 unsigned type = get_output_type(o);
78 for(const unsigned char *j=begin(); j!=end(); ++j, ++i)
79 if(get_output_type(*j)==type)
85 PixelFormat get_output_pixelformat(unsigned char o)
89 if(get_output_type(o)>=get_output_type(RENDER_DEPTH))
91 static DataType types[4] = { UNSIGNED_SHORT, UNSIGNED_SHORT, UNSIGNED_INT, FLOAT };
92 comp = DEPTH_COMPONENT;
93 type = types[(o>>2)&3];
97 static PixelComponents components[4] = { RED, RG, RGB, RGBA };
98 static DataType types[4] = { UNSIGNED_BYTE, UNSIGNED_SHORT, HALF_FLOAT, FLOAT };
99 comp = components[o&3];
100 type = types[(o>>2)&3];
103 return make_pixelformat(comp, type);
107 RenderTarget::RenderTarget(unsigned w, unsigned h, RenderOutput o)
112 RenderTarget::RenderTarget(unsigned w, unsigned h, const RenderTargetFormat &f)
117 RenderTarget::RenderTarget(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f)
122 void RenderTarget::init(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f)
129 for(const unsigned char *i=format.begin(); i!=format.end(); ++i)
131 unsigned type = get_output_type(*i);
132 FramebufferAttachment att;
133 if(type>=get_output_type(RENDER_DEPTH))
134 att = DEPTH_ATTACHMENT;
136 att = static_cast<FramebufferAttachment>(COLOR_ATTACHMENT0+type);
138 PixelFormat pf = get_output_pixelformat(*i);
143 tgt.buffer = new Renderbuffer;
144 tgt.buffer->storage_multisample(samples, pf, width, height);
145 fbo.attach(att, *tgt.buffer);
149 tgt.texture = new Texture2D;
150 tgt.texture->storage(pf, width, height, 1);
151 fbo.attach(att, *tgt.texture);
153 buffers.push_back(tgt);
157 RenderTarget::~RenderTarget()
159 for(vector<TargetBuffer>::iterator i=buffers.begin(); i!=buffers.end(); ++i)
168 const Texture2D &RenderTarget::get_target_texture(unsigned i) const
170 if(i>=buffers.size())
171 throw out_of_range("RenderTarget::get_target_texture");
173 throw invalid_operation("RenderTarget::get_target_texture");
175 return *buffers[i].texture;
178 const Texture2D &RenderTarget::get_target_texture(RenderOutput o) const
180 int index = format.index(o);
184 return get_target_texture(index);
187 void RenderTarget::set_debug_name(const string &name)
190 fbo.set_debug_name(name+" [FBO]");
192 for(const unsigned char *j=format.begin(); j!=format.end(); ++i, ++j)
194 unsigned type = get_output_type(*j);
197 if(type>=get_output_type(RENDER_DEPTH))
198 buf_name = name+"/depth";
200 buf_name = Msp::format("%s/color%d", name, type);
203 buffers[i].buffer->set_debug_name(buf_name+".tex2d");
205 buffers[i].texture->set_debug_name(buf_name+".rbuf");