From c04e98f983d0eec4605ecaf0d7f8ed67e04573eb Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 22 Oct 2018 08:40:27 +0000 Subject: [PATCH] GLPainter: Multisampled texture draw git-svn-id: svn://ultimatepp.org/upp/trunk@12386 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- bazaar/GLPainter/DrawTexture.cpp | 118 +++++++++++++++++++++++-------- bazaar/GLPainter/GLPainter.h | 13 ++-- 2 files changed, 94 insertions(+), 37 deletions(-) diff --git a/bazaar/GLPainter/DrawTexture.cpp b/bazaar/GLPainter/DrawTexture.cpp index dfe018819..b7d52b925 100644 --- a/bazaar/GLPainter/DrawTexture.cpp +++ b/bazaar/GLPainter/DrawTexture.cpp @@ -2,8 +2,13 @@ namespace Upp { +extern void (*restore_gl_viewport__)(); // in Draw/DrawUtil.cpp + void GLTextureDraw::Clear() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glActiveTexture(GL_TEXTURE0); if(texture) glDeleteTextures(1, &texture); if(rbo) @@ -11,50 +16,101 @@ void GLTextureDraw::Clear() if(framebuffer) glDeleteFramebuffers(1, &framebuffer); framebuffer = rbo = texture = 0; - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glActiveTexture(GL_TEXTURE0); + (*restore_gl_viewport__)(); } +#define GLCHK(x) do { x; { int err = glGetError(); if(err) DLOG("ERROR " << __LINE__ << ": " << #x); DLOG((const char *)gluErrorString(err)); } } while(0) + GLTexture GLTextureDraw::GetResult() { ASSERT(texture); GLTexture t; - t.Set(texture, sz); - texture = 0; - Clear(); + if(msaa > 1) { + GLuint framebuffer2, texture2, rbo2; + glGenFramebuffers(1, &framebuffer2); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2); + + glGenTextures(1, &texture2); + + glBindTexture(GL_TEXTURE_2D, texture2); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sz.cx, sz.cy, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0); + + glGenRenderbuffers(1, &rbo2); + glBindRenderbuffer(GL_RENDERBUFFER, rbo2); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, sz.cx, sz.cy); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NEVER_("Failed to create texture draw framebuffer"); + + GLCHK(glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer)); + DLOG((const char *)gluErrorString(glGetError())); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer2); + DLOG((const char *)gluErrorString(glGetError())); + glBlitFramebuffer(0, 0, sz.cx, sz.cy, 0, 0, sz.cx, sz.cy, GL_COLOR_BUFFER_BIT, GL_NEAREST); + DLOG((const char *)gluErrorString(glGetError())); + + t.Set(texture2, sz); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glActiveTexture(GL_TEXTURE0); + glDeleteRenderbuffers(1, &rbo2); + glDeleteFramebuffers(1, &framebuffer2); + Clear(); + } + else { + t.Set(texture, sz); + texture = 0; + Clear(); + } return t; } -void GLTextureDraw::Create(Size sz_) +void GLTextureDraw::Create(Size sz_, int msaa_) { sz = sz_; + msaa = msaa_; - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + + glGenTextures(1, &texture); + + if(msaa > 1) { + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture); + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, msaa, GL_RGBA, sz.cx, sz.cy, GL_TRUE); + glEnable(GL_MULTISAMPLE); + } + else { + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sz.cx, sz.cy, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } - glGenTextures(1, &texture); - - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture); - glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, sz.cx, sz.cy, GL_TRUE); - -// glBindTexture(GL_TEXTURE_2D, texture); -// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, sz.cx, sz.cy, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); // TODO: A - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); - - glGenRenderbuffers(1, &rbo); - glBindRenderbuffer(GL_RENDERBUFFER, rbo); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA8, sz.cx, sz.cy); -// glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, sz.cx, sz.cy); -// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, sz.cx, sz.cy); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - NEVER_("Texture draw has failed"); - - glClearColor(0.5f, 0.5f, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + + GLCHK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture, 0)); + + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + if(msaa > 1) + GLCHK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_DEPTH24_STENCIL8, sz.cx, sz.cy)); + else + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, sz.cx, sz.cy); + GLCHK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo)); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NEVER_("Failed to create texture draw framebuffer"); + + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glViewport(0, 0, sz.cx, sz.cy); } }; \ No newline at end of file diff --git a/bazaar/GLPainter/GLPainter.h b/bazaar/GLPainter/GLPainter.h index e25aa728e..d2c7dd88a 100644 --- a/bazaar/GLPainter/GLPainter.h +++ b/bazaar/GLPainter/GLPainter.h @@ -88,16 +88,17 @@ class GLTextureDraw { GLuint texture = 0; GLuint rbo = 0; Size sz; + int msaa = 0; public: void Clear(); - void Create(Size sz); + void Create(Size sz, int msaa = 0); GLTexture GetResult(); - operator GLTexture() { return GetResult(); } - - GLTextureDraw() {} - GLTextureDraw(Size sz) { Create(sz); } - ~GLTextureDraw() { Clear(); } + operator GLTexture() { return GetResult(); } + + GLTextureDraw() {} + GLTextureDraw(Size sz, int msaa = 0) { Create(sz, msaa); } + ~GLTextureDraw() { Clear(); } }; class GLVertexData {