1 #include <msp/core/maputils.h>
3 #include "renderbuffer.h"
4 #include "rendertarget.h"
11 RenderTargetFormat::RenderTargetFormat():
15 RenderTargetFormat::RenderTargetFormat(RenderOutput o):
21 RenderTargetFormat RenderTargetFormat::operator,(RenderOutput o) const
23 if(count>=MAX_OUTPUTS)
24 throw invalid_operation("RenderTargetFormat::operator,");
26 RenderTargetFormat result = *this;
27 result.outputs[result.count++] = o;
32 RenderTargetFormat RenderTargetFormat::operator,(PixelFormat f) const
35 throw invalid_operation("RenderTargetFormat::operator,");
37 PixelComponents comp = get_components(f);
38 DataType type = get_component_type(f);
40 unsigned char out = outputs[count-1];
41 if(get_output_type(out)>=get_output_type(RENDER_DEPTH))
43 if(comp!=DEPTH_COMPONENT)
44 throw invalid_argument("RenderTargetFormat::operator,");
47 case UNSIGNED_SHORT: size = 0; break;
48 case UNSIGNED_INT: size = 2; break;
49 case FLOAT: size = 3; break;
50 default: throw invalid_argument("RenderTargetFormat::operator,");
55 if(comp!=RED && comp!=RG && comp!=RGB && comp!=RGBA)
56 throw invalid_argument("RenderTargetformat::operator,");
59 case UNSIGNED_BYTE: size = 0; break;
60 case HALF_FLOAT: size = 2; break;
61 case FLOAT: size = 3; break;
62 default: throw invalid_argument("RenderTargetFormat::operator,");
66 out = (out&~15) | (size<<2) | (get_component_count(f)-1);
67 RenderTargetFormat result = *this;
68 result.outputs[result.count-1] = out;
73 int RenderTargetFormat::index(RenderOutput o) const
75 unsigned type = get_output_type(o);
77 for(const unsigned char *j=begin(); j!=end(); ++j, ++i)
78 if(get_output_type(*j)==type)
84 PixelFormat get_output_pixelformat(unsigned char o)
88 if(get_output_type(o)>=get_output_type(RENDER_DEPTH))
90 static DataType types[4] = { UNSIGNED_SHORT, UNSIGNED_SHORT, UNSIGNED_INT, FLOAT };
91 comp = DEPTH_COMPONENT;
92 type = types[(o>>2)&3];
96 static PixelComponents components[4] = { RED, RG, RGB, RGBA };
97 static DataType types[4] = { UNSIGNED_BYTE, UNSIGNED_SHORT, HALF_FLOAT, FLOAT };
98 comp = components[o&3];
99 type = types[(o>>2)&3];
102 return make_pixelformat(comp, type);
106 RenderTarget::RenderTarget(unsigned w, unsigned h, RenderOutput o)
111 RenderTarget::RenderTarget(unsigned w, unsigned h, const RenderTargetFormat &f)
116 RenderTarget::RenderTarget(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f)
121 void RenderTarget::init(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f)
128 for(const unsigned char *i=format.begin(); i!=format.end(); ++i)
130 unsigned type = get_output_type(*i);
131 FramebufferAttachment att;
132 if(type>=get_output_type(RENDER_DEPTH))
133 att = DEPTH_ATTACHMENT;
135 att = static_cast<FramebufferAttachment>(COLOR_ATTACHMENT0+type);
137 PixelFormat pf = get_output_pixelformat(*i);
142 tgt.buffer = new Renderbuffer;
143 tgt.buffer->storage_multisample(samples, pf, width, height);
144 fbo.attach(att, *tgt.buffer);
148 tgt.texture = new Texture2D;
149 tgt.texture->storage(pf, width, height, 1);
150 Sampler &sampler = tgt.texture->get_default_sampler();
151 sampler.set_filter(NEAREST);
152 sampler.set_wrap(CLAMP_TO_EDGE);
153 fbo.attach(att, *tgt.texture);
155 buffers.push_back(tgt);
158 fbo.require_complete();
161 RenderTarget::~RenderTarget()
163 for(vector<TargetBuffer>::iterator i=buffers.begin(); i!=buffers.end(); ++i)
172 void RenderTarget::set_texture_filter(TextureFilter filt)
176 for(vector<TargetBuffer>::iterator i=buffers.begin(); i!=buffers.end(); ++i)
177 i->texture->get_default_sampler().set_filter(filt);
181 const Texture2D &RenderTarget::get_target_texture(unsigned i) const
183 if(i>=buffers.size())
184 throw out_of_range("RenderTarget::get_target_texture");
186 throw invalid_operation("RenderTarget::get_target_texture");
188 return *buffers[i].texture;
191 const Texture2D &RenderTarget::get_target_texture(RenderOutput o) const
193 int index = format.index(o);
197 return get_target_texture(index);
200 void RenderTarget::blit_from(const RenderTarget &other)
202 fbo.blit_from(other.fbo, COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT, false);