--- /dev/null
+#include <msp/gl/extensions/arb_direct_state_access.h>
+#include <msp/gl/extensions/ext_framebuffer_multisample.h>
+#include <msp/gl/extensions/ext_framebuffer_object.h>
+#include "misc.h"
+#include "renderbuffer.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+Renderbuffer::Renderbuffer()
+{
+ static Require _req(EXT_framebuffer_object);
+
+ if(ARB_direct_state_access)
+ glCreateRenderbuffers(1, &id);
+ else
+ glGenRenderbuffers(1, &id);
+}
+
+Renderbuffer::~Renderbuffer()
+{
+ glDeleteRenderbuffers(1, &id);
+}
+
+void Renderbuffer::storage(PixelFormat fmt, unsigned wd, unsigned ht)
+{
+ require_pixelformat(fmt);
+ width = wd;
+ height = ht;
+ if(ARB_direct_state_access)
+ glNamedRenderbufferStorage(id, fmt, width, height);
+ else
+ {
+ BindRestore _bind(this);
+ glRenderbufferStorage(GL_RENDERBUFFER, fmt, width, height);
+ }
+}
+
+unsigned Renderbuffer::get_max_samples()
+{
+ static unsigned max_samples = (EXT_framebuffer_multisample ? get_i(GL_MAX_SAMPLES) : 0);
+ return max_samples;
+}
+
+void Renderbuffer::storage_multisample(unsigned samples, PixelFormat fmt, unsigned wd, unsigned ht)
+{
+ if(!samples)
+ return storage(fmt, wd, ht);
+
+ static Require _req(EXT_framebuffer_multisample);
+ if(samples>get_max_samples())
+ throw out_of_range("Renderbuffer::storage_multisample");
+
+ require_pixelformat(fmt);
+
+ width = wd;
+ height = ht;
+ if(ARB_direct_state_access)
+ glNamedRenderbufferStorageMultisample(id, samples, fmt, width, height);
+ else
+ {
+ BindRestore _bind(this);
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, fmt, width, height);
+ }
+}
+
+void Renderbuffer::bind() const
+{
+ if(set_current(this))
+ glBindRenderbuffer(GL_RENDERBUFFER, id);
+}
+
+void Renderbuffer::unbind()
+{
+ if(set_current(0))
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+}
+
+} // namespace GL
+} // namespace Msp