1 #include <msp/core/maputils.h>
2 #include <msp/strings/format.h>
4 #include "rendertarget.h"
6 #include "texture2dmultisample.h"
13 RenderTargetFormat::RenderTargetFormat():
17 RenderTargetFormat::RenderTargetFormat(RenderOutput o):
23 RenderTargetFormat RenderTargetFormat::operator,(RenderOutput o) const
25 if(count>=MAX_OUTPUTS)
26 throw invalid_operation("RenderTargetFormat::operator,");
28 RenderTargetFormat result = *this;
29 result.outputs[result.count++] = o;
34 RenderTargetFormat RenderTargetFormat::operator,(PixelFormat f) const
37 throw invalid_operation("RenderTargetFormat::operator,");
39 PixelComponents comp = get_components(f);
40 DataType type = get_component_type(f);
42 unsigned char out = outputs[count-1];
43 if(get_output_type(out)>=get_output_type(RENDER_DEPTH))
45 if(comp!=DEPTH_COMPONENT)
46 throw invalid_argument("RenderTargetFormat::operator,");
49 case UNSIGNED_SHORT: size = 0; break;
50 case UNSIGNED_INT: size = 2; break;
51 case FLOAT: size = 3; break;
52 default: throw invalid_argument("RenderTargetFormat::operator,");
57 if(comp!=RED && comp!=RG && comp!=RGB && comp!=RGBA)
58 throw invalid_argument("RenderTargetformat::operator,");
61 case UNSIGNED_BYTE: size = 0; break;
62 case HALF_FLOAT: size = 2; break;
63 case FLOAT: size = 3; break;
64 default: throw invalid_argument("RenderTargetFormat::operator,");
68 out = (out&~15) | (size<<2) | (get_component_count(f)-1);
69 RenderTargetFormat result = *this;
70 result.outputs[result.count-1] = out;
75 int RenderTargetFormat::index(RenderOutput o) const
77 unsigned type = get_output_type(o);
79 for(const unsigned char *j=begin(); j!=end(); ++j, ++i)
80 if(get_output_type(*j)==type)
86 PixelFormat get_output_pixelformat(unsigned char o)
90 if(get_output_type(o)>=get_output_type(RENDER_DEPTH))
92 static DataType types[4] = { UNSIGNED_SHORT, UNSIGNED_SHORT, UNSIGNED_INT, FLOAT };
93 comp = DEPTH_COMPONENT;
94 type = types[(o>>2)&3];
98 static PixelComponents components[4] = { RED, RG, RGB, RGBA };
99 static DataType types[4] = { UNSIGNED_BYTE, UNSIGNED_SHORT, HALF_FLOAT, FLOAT };
100 comp = components[o&3];
101 type = types[(o>>2)&3];
104 return make_pixelformat(comp, type);
108 RenderTarget::RenderTarget(unsigned w, unsigned h, RenderOutput o)
113 RenderTarget::RenderTarget(unsigned w, unsigned h, const RenderTargetFormat &f)
118 RenderTarget::RenderTarget(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f)
123 void RenderTarget::init(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f)
130 for(const unsigned char *i=format.begin(); i!=format.end(); ++i)
132 unsigned type = get_output_type(*i);
133 FramebufferAttachment att;
134 if(type>=get_output_type(RENDER_DEPTH))
135 att = DEPTH_ATTACHMENT;
137 att = static_cast<FramebufferAttachment>(COLOR_ATTACHMENT0+type);
139 PixelFormat pf = get_output_pixelformat(*i);
143 Texture2DMultisample *tex2d_ms = new Texture2DMultisample;
144 tex2d_ms->storage(pf, width, height, samples);
145 fbo.attach(att, *tex2d_ms);
146 textures.push_back(tex2d_ms);
150 Texture2D *tex2d = new Texture2D;
151 tex2d->storage(pf, width, height, 1);
152 fbo.attach(att, *tex2d);
153 textures.push_back(tex2d);
158 RenderTarget::~RenderTarget()
160 for(vector<Texture *>::iterator i=textures.begin(); i!=textures.end(); ++i)
164 const Texture2D &RenderTarget::get_target_texture(unsigned i) const
166 if(i>=textures.size())
167 throw out_of_range("RenderTarget::get_target_texture");
169 throw invalid_operation("RenderTarget::get_target_texture");
171 return *static_cast<const Texture2D *>(textures[i]);
174 const Texture2D &RenderTarget::get_target_texture(RenderOutput o) const
176 int index = format.index(o);
180 return get_target_texture(index);
183 void RenderTarget::set_debug_name(const string &name)
186 fbo.set_debug_name(name+" [FBO]");
188 for(const unsigned char *j=format.begin(); j!=format.end(); ++i, ++j)
190 unsigned type = get_output_type(*j);
193 if(type>=get_output_type(RENDER_DEPTH))
194 tex_name = name+"/depth";
196 tex_name = Msp::format("%s/color%d", name, type);
198 textures[i]->set_debug_name(tex_name+".tex2d");