/*
	QGL Framebuffer effect basic
    Ivan Pelipenko peri4ko@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "glframebuffereffectbase.h"

#include "renderer.h"

#include <QTime>


FramebufferEffectBase::FramebufferEffectBase() {}


FramebufferEffectBase::~FramebufferEffectBase() {
	/*if (fbo > 0) deleteGLFramebuffer(fbo);
	deleteGLRenderbuffer(drbo);
	for (int i = 0; i < colors.size(); ++i)
		deleteGLTexture(f, colors[i]);
	deleteGLTexture(f, tex_d);*/
}


void FramebufferEffectBase::resize(int width, int height, bool force) {
	/*if (fbo > 0) {
		if ((wid == width) && (hei == height) && !force) return;
	}
	wid = width;
	hei = height;
	if (fbo > 0) deleteGLFramebuffer(fbo);
	f->glGenFramebuffers(1, &fbo);
	f->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	// qDebug() << "resize" << f << wid << hei << fbo;
	for (int i = 0; i < colors.size(); ++i) {
		deleteGLTexture(f, colors[i]);
		createGLTexture(f, colors[i], width, height, color_formats[i], target_);
		f->glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		f->glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		f->glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		f->glTexParameteri(target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		f->glTexParameteri(target_, GL_TEXTURE_MAX_LEVEL, 4);
		f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, target_, colors[i], 0);
	}
	if (is_depth) {
		deleteGLTexture(f, tex_d);
		if (drbo > 0) deleteGLRenderbuffer(drbo);
		f->glGenRenderbuffers(1, &drbo);
		f->glBindRenderbuffer(GL_RENDERBUFFER, drbo);
		f->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
		f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, drbo);
		createGLTexture(f, tex_d, width, height, GL_DEPTH_COMPONENT);
		f->glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		f->glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		f->glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		f->glTexParameteri(target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target_, tex_d, 0);
	}
	f->glBindFramebuffer(GL_FRAMEBUFFER, 0);
	if (pbo.isInit()) {
		enablePixelBuffer();
	}
	is_changed = false;*/
}


void FramebufferEffectBase::reinit() {
	/*pbo.reinit();
	colors.fill(0);
	fbo = drbo  = 0;
	tex_d       = 0;
	pbo_queried = 0;
	is_changed  = true;*/
}


void FramebufferEffectBase::bindDeferredBuffer(int role, int channel) {
	r->fbo_ds.bindColorTexture(role, channel);
}


void FramebufferEffectBase::bindDepthBuffer(int channel) {
	r->fbo_ds.bindDepthTexture(channel);
}


void FramebufferEffectBase::bindPreviousOutput(int channel) {
	r->fbo_out.bindColorTexture(r->prev_write_plane, channel);
}


void FramebufferEffectBase::setOutputPlane(int channel) {
	r->fbo_out.setWriteBuffer(channel);
	r->prev_write_plane = r->cur_write_plane;
	r->cur_write_plane  = channel;
}


void FramebufferEffectBase::drawScreen(QOpenGLShaderProgram * prog) {
	r->renderQuad(prog, r->quad, nullptr);
}


void FramebufferEffectBase::drawInternal() {
	if (!r) return;
	draw();
}


void FramebufferEffectBase::reloadShadersInternal() {
	if (!r) return;
	if (is_loaded) return;
	reloadShaders();
	is_loaded = true;
}


QVector<int> FramebufferEffectBase::getFreePlanes(int count) {
	return r->getFreePlanes(count);
}


int FramebufferEffectBase::previousOutputPlane() const {
	return r->prev_write_plane;
}


void FramebufferEffectBase::deleteShader(QOpenGLShaderProgram *& s) {
	if (!s) return;
	delete s;
	s = nullptr;
}
