+#include <msp/gl/extensions/arb_draw_buffers.h>
+#include <msp/gl/extensions/ext_framebuffer_blit.h>
+#include <msp/gl/extensions/ext_framebuffer_object.h>
#include "error.h"
-#include "ext_framebuffer_blit.h"
-#include "ext_framebuffer_object.h"
#include "framebuffer.h"
#include "misc.h"
#include "renderbuffer.h"
namespace Msp {
namespace GL {
+void operator<<(LexicalConverter &conv, FramebufferStatus status)
+{
+ switch(status)
+ {
+ case FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ conv.result("incomplete attachment");
+ break;
+ case FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ conv.result("missing attachment");
+ break;
+ case FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+ conv.result("mismatched attachment dimensions");
+ break;
+ case FRAMEBUFFER_INCOMPLETE_FORMATS:
+ conv.result("mismatched attachment formats");
+ break;
+ case FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+ conv.result("missing draw buffer attachment");
+ break;
+ case FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+ conv.result("missing read buffer attachment");
+ break;
+ case FRAMEBUFFER_UNSUPPORTED:
+ conv.result("unsupported");
+ break;
+ default:
+ conv.result(lexical_cast<string, unsigned>(status, "%#x"));
+ break;
+ }
+}
+
+framebuffer_incomplete::framebuffer_incomplete(FramebufferStatus status):
+ runtime_error(lexical_cast<string>(status))
+{ }
+
+
Framebuffer::Framebuffer(unsigned i):
id(i),
dirty(0)
{
if(current()==this)
{
- GLenum color_buf = GL_NONE;
+ std::vector<GLenum> color_bufs;
+ color_bufs.reserve(attachments.size());
for(unsigned i=0; i<attachments.size(); ++i)
{
const Attachment &attch = attachments[i];
}
if(attch.attachment>=COLOR_ATTACHMENT0 && attch.attachment<=COLOR_ATTACHMENT3)
- color_buf = attch.attachment;
+ color_bufs.push_back(attch.attachment);
}
- glDrawBuffer(color_buf);
+ if(color_bufs.empty())
+ {
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+ }
+ else if(color_bufs.size()==1)
+ {
+ glDrawBuffer(color_bufs.front());
+ glReadBuffer(color_bufs.front());
+ }
+ else
+ {
+ static Require _req(ARB_draw_buffers);
+ glDrawBuffers(color_bufs.size(), &color_bufs[0]);
+ glReadBuffer(color_bufs.front());
+ }
}
else
dirty |= mask;
return static_cast<FramebufferStatus>(glCheckFramebufferStatus(GL_FRAMEBUFFER));
}
+void Framebuffer::require_complete() const
+{
+ FramebufferStatus status = check_status();
+ if(status!=FRAMEBUFFER_COMPLETE)
+ throw framebuffer_incomplete(status);
+}
+
void Framebuffer::clear(BufferBits bits)
{
Bind _bind(this, true);