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 PixelFormat unsized = get_unsized_pixelformat(f);
38 unsigned size = get_component_size(f);
39 unsigned char out = outputs[count-1];
40 if(get_output_type(out)>=get_output_type(RENDER_DEPTH))
42 if(unsized!=DEPTH_COMPONENT)
43 throw invalid_argument("RenderTargetformat::operator,");
49 if(unsized!=RED && unsized!=RG && unsized!=RGB && unsized!=RGBA)
50 throw invalid_argument("RenderTargetformat::operator,");
55 out = (out&~15) | (size<<2) | (get_component_count(f)-1);
56 RenderTargetFormat result = *this;
57 result.outputs[result.count-1] = out;
62 int RenderTargetFormat::index(RenderOutput o) const
64 unsigned type = get_output_type(o);
66 for(const unsigned char *j=begin(); j!=end(); ++j, ++i)
67 if(get_output_type(*j)==type)
73 PixelFormat get_output_pixelformat(unsigned char o)
75 unsigned size = ((o>>2)&3);
77 if(get_output_type(o)>=get_output_type(RENDER_DEPTH))
79 base = DEPTH_COMPONENT;
85 static PixelFormat base_formats[4] = { RED, RG, RGB, RGBA };
86 base = base_formats[o&3];
92 return get_sized_pixelformat(base, size);
98 RenderTarget::RenderTarget(unsigned w, unsigned h, const RenderTargetFormat &f)
103 RenderTarget::RenderTarget(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f)
108 void RenderTarget::init(unsigned w, unsigned h, unsigned s, const RenderTargetFormat &f)
115 for(const unsigned char *i=format.begin(); i!=format.end(); ++i)
117 unsigned type = get_output_type(*i);
118 FramebufferAttachment att;
119 if(type>=get_output_type(RENDER_DEPTH))
120 att = DEPTH_ATTACHMENT;
122 att = static_cast<FramebufferAttachment>(COLOR_ATTACHMENT0+type);
124 PixelFormat pf = get_output_pixelformat(*i);
129 tgt.buffer = new Renderbuffer;
130 tgt.buffer->storage_multisample(samples, pf, width, height);
131 fbo.attach(att, *tgt.buffer);
135 tgt.texture = new Texture2D;
136 tgt.texture->storage(pf, width, height, 1);
137 tgt.texture->set_filter(NEAREST);
138 tgt.texture->set_wrap(CLAMP_TO_EDGE);
139 fbo.attach(att, *tgt.texture);
141 buffers.push_back(tgt);
144 fbo.require_complete();
147 RenderTarget::~RenderTarget()
149 for(vector<TargetBuffer>::iterator i=buffers.begin(); i!=buffers.end(); ++i)
158 void RenderTarget::set_texture_filter(TextureFilter filt)
162 for(vector<TargetBuffer>::iterator i=buffers.begin(); i!=buffers.end(); ++i)
163 i->texture->set_filter(filt);
167 const Texture2D &RenderTarget::get_target_texture(unsigned i) const
169 if(i>=buffers.size())
170 throw out_of_range("RenderTarget::get_target_texture");
172 throw invalid_operation("RenderTarget::get_target_texture");
174 return *buffers[i].texture;
177 const Texture2D &RenderTarget::get_target_texture(RenderOutput o) const
179 int index = format.index(o);
183 return get_target_texture(index);
186 void RenderTarget::blit_from(const RenderTarget &other)
188 fbo.blit_from(other.fbo, COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT, false);