}
}
+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)
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);
void OpenGLFramebuffer::resize_system(unsigned w, unsigned h)
{
- Framebuffer *self = static_cast<Framebuffer *>(this);
- self->width = w;
- self->height = h;
+ Framebuffer &self = *static_cast<Framebuffer *>(this);
+ self.width = w;
+ self.height = h;
}
void OpenGLFramebuffer::update(unsigned mask) const
{
- const FrameFormat &format = static_cast<const Framebuffer *>(this)->format;
+ const Framebuffer &self = *static_cast<const Framebuffer *>(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<const Framebuffer *>(this);
+ unsigned obj_id = (resolve ? resolve_id : id);
+ Texture *Framebuffer::Attachment::*member = (resolve ? &Framebuffer::Attachment::resolve : &Framebuffer::Attachment::tex);
+
vector<GLenum> 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<<i))
{
- const Framebuffer::Attachment &attch = static_cast<const Framebuffer *>(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<TextureCubeFace>(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<TextureCubeFace>(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);
}
{
/* 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
{
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
{
#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