X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbackends%2Fopengl%2Fframebuffer_backend.cpp;h=8ba947dfe1eb0528e91521fa3d853ec04a74e082;hb=94cadd1618f93239b1cb0acbd4f958257c035c98;hp=b56499d1609186572a8ada56492163c0bfbfaf1b;hpb=b9e720f36185c6fe4d39a1056ecb88dec0ce950d;p=libs%2Fgl.git diff --git a/source/backends/opengl/framebuffer_backend.cpp b/source/backends/opengl/framebuffer_backend.cpp index b56499d1..8ba947df 100644 --- a/source/backends/opengl/framebuffer_backend.cpp +++ b/source/backends/opengl/framebuffer_backend.cpp @@ -19,7 +19,6 @@ namespace Msp { namespace GL { OpenGLFramebuffer::OpenGLFramebuffer(bool is_system): - id(0), status(is_system ? GL_FRAMEBUFFER_COMPLETE : GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) { if(!is_system) @@ -33,10 +32,19 @@ OpenGLFramebuffer::OpenGLFramebuffer(bool is_system): } } +OpenGLFramebuffer::OpenGLFramebuffer(OpenGLFramebuffer &&other): + id(other.id), + status(other.status) +{ + other.id = 0; +} + OpenGLFramebuffer::~OpenGLFramebuffer() { if(id) glDeleteFramebuffers(1, &id); + if(resolve_id) + glDeleteFramebuffers(1, &resolve_id); } void OpenGLFramebuffer::set_system_format(const FrameFormat &fmt) @@ -63,6 +71,17 @@ bool OpenGLFramebuffer::is_format_supported(const FrameFormat &fmt) return true; } +void OpenGLFramebuffer::format_changed(const FrameFormat &format) +{ + if(format.get_samples()>1 && !resolve_id) + { + if(ARB_direct_state_access) + glCreateFramebuffers(1, &resolve_id); + else + glGenFramebuffers(1, &resolve_id); + } +} + void OpenGLFramebuffer::require_layered() { static Require _req(ARB_geometry_shader4); @@ -70,45 +89,66 @@ void OpenGLFramebuffer::require_layered() void OpenGLFramebuffer::resize_system(unsigned w, unsigned h) { - Framebuffer *self = static_cast(this); - self->width = w; - self->height = h; + Framebuffer &self = *static_cast(this); + self.width = w; + self.height = h; } void OpenGLFramebuffer::update(unsigned mask) const { - const FrameFormat &format = static_cast(this)->format; + const Framebuffer &self = *static_cast(this); + + update(mask, false); + if(self.has_resolve_attachments()) + { + if(!ARB_direct_state_access) + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_id); + + update(mask, true); + + if(!ARB_direct_state_access) + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, id); + } +} + +void OpenGLFramebuffer::update(unsigned mask, bool resolve) const +{ + const Framebuffer &self = *static_cast(this); + unsigned obj_id = (resolve ? resolve_id : id); + Texture *Framebuffer::Attachment::*member = (resolve ? &Framebuffer::Attachment::resolve : &Framebuffer::Attachment::tex); + vector color_bufs; - color_bufs.reserve(format.size()); + color_bufs.reserve(self.format.size()); unsigned i = 0; - for(FrameAttachment a: format) + for(FrameAttachment a: self.format) { GLenum gl_attach_point = get_gl_attachment(a); if(mask&(1<(this)->attachments[i]; - if(attch.tex) + const Framebuffer::Attachment &attch = self.attachments[i]; + Texture *tex = attch.*member; + if(tex) { if(ARB_direct_state_access) { - if(attch.tex->target==GL_TEXTURE_2D || attch.tex->target==GL_TEXTURE_2D_MULTISAMPLE || attch.layer<0) - glNamedFramebufferTexture(id, gl_attach_point, attch.tex->id, attch.level); + if(tex->target==GL_TEXTURE_2D || tex->target==GL_TEXTURE_2D_MULTISAMPLE || attch.layer<0) + glNamedFramebufferTexture(obj_id, gl_attach_point, tex->id, attch.level); else - glNamedFramebufferTextureLayer(id, gl_attach_point, attch.tex->id, attch.level, attch.layer); + glNamedFramebufferTextureLayer(obj_id, gl_attach_point, tex->id, attch.level, attch.layer); } - else if(attch.tex->target==GL_TEXTURE_2D || attch.tex->target==GL_TEXTURE_2D_MULTISAMPLE) - glFramebufferTexture2D(GL_FRAMEBUFFER, gl_attach_point, attch.tex->target, attch.tex->id, attch.level); + else if(tex->target==GL_TEXTURE_2D || tex->target==GL_TEXTURE_2D_MULTISAMPLE) + glFramebufferTexture2D(GL_FRAMEBUFFER, gl_attach_point, tex->target, tex->id, attch.level); else if(attch.layer<0) - glFramebufferTexture(GL_FRAMEBUFFER, gl_attach_point, attch.tex->id, attch.level); - else if(attch.tex->target==GL_TEXTURE_2D_ARRAY) - glFramebufferTextureLayer(GL_FRAMEBUFFER, gl_attach_point, attch.tex->id, attch.level, attch.layer); - else if(attch.tex->target==GL_TEXTURE_3D) - glFramebufferTexture3D(GL_FRAMEBUFFER, gl_attach_point, attch.tex->target, attch.tex->id, attch.level, attch.layer); - else if(attch.tex->target==GL_TEXTURE_CUBE_MAP) - glFramebufferTexture2D(GL_FRAMEBUFFER, gl_attach_point, get_gl_cube_face(static_cast(attch.layer)), attch.tex->id, attch.level); + glFramebufferTexture(GL_FRAMEBUFFER, gl_attach_point, tex->id, attch.level); + else if(tex->target==GL_TEXTURE_2D_ARRAY) + glFramebufferTextureLayer(GL_FRAMEBUFFER, gl_attach_point, tex->id, attch.level, attch.layer); + else if(tex->target==GL_TEXTURE_3D) + glFramebufferTexture3D(GL_FRAMEBUFFER, gl_attach_point, tex->target, tex->id, attch.level, attch.layer); + else if(tex->target==GL_TEXTURE_CUBE_MAP) + glFramebufferTexture2D(GL_FRAMEBUFFER, gl_attach_point, get_gl_cube_face(static_cast(attch.layer)), tex->id, attch.level); } else if(ARB_direct_state_access) - glNamedFramebufferTexture(id, gl_attach_point, 0, 0); + glNamedFramebufferTexture(obj_id, gl_attach_point, 0, 0); else glFramebufferTexture2D(GL_FRAMEBUFFER, gl_attach_point, GL_TEXTURE_2D, 0, 0); } @@ -127,8 +167,8 @@ void OpenGLFramebuffer::update(unsigned mask) const { /* ARB_direct_state_access ties the availability of these functions to framebuffers themselves, so no further checks are needed. */ - glNamedFramebufferDrawBuffers(id, color_bufs.size(), &color_bufs[0]); - glNamedFramebufferReadBuffer(id, first_buffer); + glNamedFramebufferDrawBuffers(obj_id, color_bufs.size(), &color_bufs[0]); + glNamedFramebufferReadBuffer(obj_id, first_buffer); } else { @@ -141,10 +181,13 @@ void OpenGLFramebuffer::update(unsigned mask) const glReadBuffer(first_buffer); } - if(ARB_direct_state_access) - status = glCheckNamedFramebufferStatus(id, GL_FRAMEBUFFER); - else - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if(!resolve) + { + if(ARB_direct_state_access) + status = glCheckNamedFramebufferStatus(obj_id, GL_FRAMEBUFFER); + else + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + } } void OpenGLFramebuffer::require_complete() const @@ -161,7 +204,14 @@ void OpenGLFramebuffer::set_debug_name(const string &name) { #ifdef DEBUG if(KHR_debug) + { glObjectLabel(GL_FRAMEBUFFER, id, name.size(), name.c_str()); + if(resolve_id) + { + string resolve_name = name+" [resolve]"; + glObjectLabel(GL_FRAMEBUFFER, resolve_id, resolve_name.size(), resolve_name.c_str()); + } + } #else (void)name; #endif