+++ /dev/null
-#include <msp/core/maputils.h>
-#include "error.h"
-#include "renderbuffer.h"
-#include "rendertarget.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
-{
- 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,");
-
- PixelFormat unsized = get_unsized_pixelformat(f);
- unsigned size = get_component_size(f);
- unsigned char out = outputs[count-1];
- if(get_output_type(out)>=get_output_type(RENDER_DEPTH))
- {
- if(unsized!=DEPTH_COMPONENT)
- throw invalid_argument("RenderTargetformat::operator,");
- if(size>1)
- --size;
- }
- else
- {
- if(unsized!=RED && unsized!=RG && unsized!=RGB && unsized!=RGBA)
- throw invalid_argument("RenderTargetformat::operator,");
- if(size>3)
- --size;
- }
-
- 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 get_output_pixelformat(unsigned char o)
-{
- unsigned size = ((o>>2)&3);
- PixelFormat base;
- if(get_output_type(o)>=get_output_type(RENDER_DEPTH))
- {
- base = DEPTH_COMPONENT;
- if(size)
- ++size;
- }
- else
- {
- static PixelFormat base_formats[4] = { RED, RG, RGB, RGBA };
- base = base_formats[o&3];
- if(size==3)
- ++size;
- }
-
- if(size)
- return get_sized_pixelformat(base, size);
- else
- return base;
-}
-
-
-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)
- {
- tgt.buffer = new Renderbuffer;
- tgt.buffer->storage_multisample(samples, pf, width, height);
- fbo.attach(att, *tgt.buffer);
- }
- else
- {
- tgt.texture = new Texture2D;
- tgt.texture->storage(pf, width, height, 1);
- tgt.texture->set_filter(NEAREST);
- tgt.texture->set_wrap(CLAMP_TO_EDGE);
- fbo.attach(att, *tgt.texture);
- }
- 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;
- }
-}
-
-void RenderTarget::set_texture_filter(TextureFilter filt)
-{
- if(!samples)
- {
- for(vector<TargetBuffer>::iterator i=buffers.begin(); i!=buffers.end(); ++i)
- i->texture->set_filter(filt);
- }
-}
-
-const Texture2D &RenderTarget::get_target_texture(unsigned i) const
-{
- if(i>=buffers.size())
- throw out_of_range("RenderTarget::get_target_texture");
- if(samples)
- throw invalid_operation("RenderTarget::get_target_texture");
-
- return *buffers[i].texture;
-}
-
-const Texture2D &RenderTarget::get_target_texture(RenderOutput o) const
-{
- int index = format.index(o);
- if(index<0)
- throw key_error(o);
-
- return get_target_texture(index);
-}
-
-void RenderTarget::blit_from(const RenderTarget &other)
-{
- fbo.blit_from(other.fbo, COLOR_BUFFER_BIT|DEPTH_BUFFER_BIT, false);
-}
-
-} // namespace GL
-} // namespace Msp