137 lines
4.3 KiB
C++
137 lines
4.3 KiB
C++
/*
|
|
QGLView
|
|
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "glframebuffer.h"
|
|
|
|
|
|
GLFramebuffer::GLFramebuffer(int colorAttachments_, bool withDepth, GLenum colorFormat_, GLenum target__) {
|
|
is_depth = withDepth;
|
|
color_format = colorFormat_;
|
|
target_ = target__;
|
|
colors.fill(0, colorAttachments_);
|
|
fbo = drbo = 0;
|
|
tex_d = 0;
|
|
wid = hei = 0;
|
|
is_changed = false;
|
|
}
|
|
|
|
|
|
GLFramebuffer::~GLFramebuffer() {
|
|
deleteGLFramebuffer(fbo);
|
|
deleteGLRenderbuffer(drbo);
|
|
for (int i = 0; i < colors.size(); ++i)
|
|
deleteGLTexture(colors[i]);
|
|
deleteGLTexture(tex_d);
|
|
}
|
|
|
|
|
|
void GLFramebuffer::resize(int width, int height) {
|
|
wid = width;
|
|
hei = height;
|
|
deleteGLFramebuffer(fbo);
|
|
glGenFramebuffers(1, &fbo);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
|
for (int i = 0; i < colors.size(); ++i) {
|
|
deleteGLTexture(colors[i]);
|
|
createGLTexture(colors[i], width, height, color_format, target_);
|
|
glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(target_, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, target_, colors[i], 0);
|
|
}
|
|
if (is_depth) {
|
|
deleteGLTexture(tex_d);
|
|
deleteGLRenderbuffer(drbo);
|
|
glGenRenderbuffers(1, &drbo);
|
|
glBindRenderbuffer(GL_RENDERBUFFER, drbo);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, drbo);
|
|
createGLTexture(tex_d, width, height, GL_DEPTH_COMPONENT);
|
|
glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(target_, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target_, tex_d, 0);
|
|
}
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
is_changed = false;
|
|
}
|
|
|
|
|
|
void GLFramebuffer::bind() {
|
|
if (is_changed) resize(wid, hei);
|
|
if (fbo == 0) return;
|
|
glFlush();
|
|
glGetIntegerv(GL_VIEWPORT, prev_view);
|
|
//glClearError();
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
|
//qDebug() << QString::number(glGetError(), 16);
|
|
QVector<GLenum> buffers;
|
|
for (int i = 0; i < colors.size(); ++i)
|
|
buffers << GL_COLOR_ATTACHMENT0 + i;
|
|
glDrawBuffers(buffers.size(), buffers.constData());
|
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
|
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
|
glViewport(0, 0, wid, hei);
|
|
}
|
|
|
|
|
|
void GLFramebuffer::release() {
|
|
is_changed = false;
|
|
if (fbo == 0) return;
|
|
glFlush();
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
glViewport(prev_view[0], prev_view[1], prev_view[2], prev_view[3]);
|
|
}
|
|
|
|
|
|
void GLFramebuffer::setWriteBuffers(int indeces[]) {
|
|
QVector<GLenum> buffers;
|
|
for (uint i = 0; i < sizeof(indeces); ++i) {
|
|
buffers << GL_COLOR_ATTACHMENT0 + indeces[i];
|
|
}
|
|
glDrawBuffers(buffers.size(), buffers.constData());
|
|
}
|
|
|
|
|
|
void GLFramebuffer::setWriteBuffers(int * indeces, int count) {
|
|
QVector<GLenum> buffers;
|
|
for (int i = 0; i < count; ++i)
|
|
buffers << GL_COLOR_ATTACHMENT0 + indeces[i];
|
|
glDrawBuffers(buffers.size(), buffers.constData());
|
|
}
|
|
|
|
|
|
void GLFramebuffer::bindColorTextures() {
|
|
for (int i = colors.size() - 1; i >= 0; --i) {
|
|
glActiveTextureChannel(i);
|
|
glBindTexture(GL_TEXTURE_2D, colors[i]);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
}
|
|
}
|
|
|
|
|
|
void GLFramebuffer::bindDepthTexture(int channel) {
|
|
glActiveTextureChannel(channel);
|
|
glBindTexture(GL_TEXTURE_2D, tex_d);
|
|
}
|