]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/frameformat.cpp
Redesign framebuffer attachment management
[libs/gl.git] / source / core / frameformat.cpp
diff --git a/source/core/frameformat.cpp b/source/core/frameformat.cpp
new file mode 100644 (file)
index 0000000..30d7a47
--- /dev/null
@@ -0,0 +1,137 @@
+#include "deviceinfo.h"
+#include "error.h"
+#include "frameformat.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+FrameFormat::FrameFormat():
+       count(0),
+       samples(1)
+{ }
+
+FrameFormat::FrameFormat(FrameAttachment fa):
+       count(1),
+       samples(1)
+{
+       attachments[0] = fa;
+}
+
+FrameFormat FrameFormat::operator,(FrameAttachment fa) const
+{
+       if(count>=MAX_ATTACHMENTS)
+               throw invalid_operation("FrameFormat::operator,");
+
+       FrameFormat result = *this;
+       result.attachments[result.count++] = fa;
+
+       return result;
+}
+
+FrameFormat FrameFormat::operator,(PixelFormat pf) const
+{
+       if(!count)
+               throw invalid_operation("FrameFormat::operator,");
+
+       FrameFormat r = *this;
+       UInt16 &fa = r.attachments[r.count-1];
+       fa = make_typed_attachment(static_cast<FrameAttachment>(fa), pf);
+
+       return r;
+}
+
+FrameFormat FrameFormat::operator,(unsigned index) const
+{
+       if(!count)
+               throw invalid_operation("FrameFormat::operator,");
+
+       FrameFormat r = *this;
+       UInt16 &fa = r.attachments[r.count-1];
+       fa = make_indexed_attachment(static_cast<FrameAttachment>(fa), index);
+
+       return r;
+}
+
+FrameFormat &FrameFormat::set_samples(unsigned s)
+{
+       samples = s;
+       return *this;
+}
+
+int FrameFormat::index(FrameAttachment fa) const
+{
+       for(unsigned i=0; i<count; ++i)
+               if(get_attach_point(attachments[i])==get_attach_point(fa))
+                       return i;
+       return -1;
+}
+
+
+FrameAttachment make_typed_attachment(FrameAttachment fa, PixelFormat pf)
+{
+       PixelComponents comp = get_components(pf);
+       if(get_attach_point(fa)==get_attach_point(DEPTH_ATTACHMENT))
+       {
+               if(comp!=DEPTH_COMPONENT)
+                       throw invalid_argument("make_typed_attachment");
+       }
+       else if(get_attach_point(fa)==get_attach_point(STENCIL_ATTACHMENT))
+       {
+               if(comp!=STENCIL_INDEX)
+                       throw invalid_argument("make_typed_attachment");
+       }
+       else
+       {
+               if(comp!=RED && comp!=RG && comp!=RGB && comp!=RGBA)
+                       throw invalid_argument("make_typed_attachment");
+       }
+
+       DataType type = get_component_type(pf);
+       return static_cast<FrameAttachment>((fa&0xFC00) | (is_float(type)*0x80) | get_type_size(type)<<4 | get_component_count(comp));
+}
+
+FrameAttachment make_indexed_attachment(FrameAttachment fa, unsigned i)
+{
+       if(get_attach_point(fa)==get_attach_point(COLOR_ATTACHMENT))
+       {
+               if(i>61)
+                       throw out_of_range("make_indexed_attachment");
+               return static_cast<FrameAttachment>(fa+(i<<10));
+       }
+       else
+               throw invalid_argument("make_indexed_attachment");
+}
+
+PixelFormat get_attachment_pixelformat(UInt16 fa)
+{
+       PixelComponents comp;
+       if(get_attach_point(fa)==get_attach_point(DEPTH_ATTACHMENT))
+               comp = DEPTH_COMPONENT;
+       else if(get_attach_point(fa)==get_attach_point(STENCIL_ATTACHMENT))
+               comp = STENCIL_INDEX;
+       else
+               comp = static_cast<PixelComponents>(fa&7);
+
+       DataType type;
+       if(fa&0x80)
+               type = static_cast<DataType>((fa&0x70)>>4 | 0x300);
+       else
+               type = static_cast<DataType>((fa&0x70)>>4);
+
+       return make_pixelformat(comp, type);
+}
+
+GLenum get_gl_attachment(FrameAttachment fa)
+{
+       if(get_attach_point(fa)==get_attach_point(DEPTH_ATTACHMENT))
+               return GL_DEPTH_ATTACHMENT;
+       else if(get_attach_point(fa)==get_attach_point(STENCIL_ATTACHMENT))
+               return GL_STENCIL_ATTACHMENT;
+       else
+               return GL_COLOR_ATTACHMENT0+get_attach_point(fa);
+}
+
+} // namespace GL
+} // namespace Msp