This repository has been archived on 2020-09-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
libs/qglview/glframebuffer.cpp

144 lines
4.5 KiB
C++

/*
QGLView
Copyright (C) 2017 Ivan Pelipenko peri4ko@yandex.ru
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, bool force) {
if ((wid == width) && (hei == height) && !force) return;
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_TEXTURE_MAX_LEVEL, 4);
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;
}
QImage GLFramebuffer::grab() const {
//glReadPixels(0, 0, wid, hei, GL_RGBA, );
//QImage ret();
return QImage();
}
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::setWriteBuffer(int index) {
//QVector<GLenum> buffers; buffers << GL_COLOR_ATTACHMENT0 + index;
glDrawBuffer(GL_COLOR_ATTACHMENT0 + index);
//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);
}