ultimatepp/uppsrc/GLDraw/TextureDraw.cpp
cxl 963810235e GLDraw: TextureDraw fixes
git-svn-id: svn://ultimatepp.org/upp/trunk@12428 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2018-10-29 18:15:12 +00:00

119 lines
No EOL
3.7 KiB
C++

#include "GLDraw.h"
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)
glDeleteRenderbuffers(1, &rbo);
if(framebuffer)
glDeleteFramebuffers(1, &framebuffer);
framebuffer = rbo = texture = 0;
(*restore_gl_viewport__)();
}
GLTexture GLTextureDraw::GetResult()
{
ASSERT(texture);
Flush();
GLTexture t;
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_RGB, 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);
glBindTexture(GL_TEXTURE_2D, 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, rbo2);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
NEVER_("Failed to create final texture draw framebuffer");
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer2);
glBlitFramebuffer(0, 0, sz.cx, sz.cy, 0, 0, sz.cx, sz.cy, GL_COLOR_BUFFER_BIT, GL_NEAREST);
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_, int msaa_)
{
sz = sz_;
msaa = msaa_;
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_RGB, sz.cx, sz.cy, GL_TRUE);
glEnable(GL_MULTISAMPLE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
}
else {
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sz.cx, sz.cy, 0, GL_RGB, 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, msaa > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, texture, 0);
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
if(msaa > 1)
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_DEPTH24_STENCIL8, sz.cx, sz.cy);
else
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, sz.cx, sz.cy);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
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);
DrawGL::Init(sz, 1);
dd.vs.cy *= -1;
dd.off = Sizef(-1, -1);
}
};