/*
    QGLView
    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 "renderer_simple.h"


RendererSimple::RendererSimple(QGLView * view_)
	: GLRendererBase(view_)
	, fbo(2)
	, fbo_c(1, true, GL_RGBA32F) /// WARNING
{
	shader_fxaa = 0;
	shader      = 0; /// WARNING
}


void RendererSimple::reloadShaders() {
	if (shader_fxaa == 0) {
		shader_fxaa = new QOpenGLShaderProgram(view.context());
		loadShaders(shader_fxaa, "FXAA", "://shaders");
	}
	/*if (shader == 0) {
	    shader = new QOpenGLShaderProgram(view.context()); /// WARNING
	    loadShaders(shader, "test", "shaders");        /// WARNING
	}*/
}


void RendererSimple::resizeFBO(int w, int h) {
	initializeOpenGLFunctions();
	fbo.resize(w, h);
	fbo_c.resize(w, h); /// WARNING
}


void RendererSimple::renderScene() {
	int passes = (view.lightsCount() - 1) / 8 + 1;
	// QMatrix4x4 pm = getGLMatrix(GL_PROJECTION_MATRIX), mvm = getGLMatrix(GL_MODELVIEW_MATRIX), pmvm = pm * mvm, lpm, lmvm, lpmvm;
	// glSetCapEnabled(GL_MULTISAMPLE, view.isFeatureEnabled(QGLView::qglMSAA));
	if (passes < 1) passes = 1;
	// glEnable(GL_FOG);
	// if (view.isFeatureEnabled(QGLView::qglFXAA)) fbo.bind();
	// glEnable(GL_TEXTURE_2D);
	if (passes > 1 || view.isFeatureEnabled(QGLView::qglFXAA)) {
		fbo.bind();
		fbo.setWriteBuffer(0);
		glClearFramebuffer();
	} else
		glSetCapEnabled(GL_MULTISAMPLE, view.isFeatureEnabled(QGLView::qglMSAA));
	glEnable(GL_RESCALE_NORMAL);
	for (int l = 0; l < passes; ++l) {
		if (passes > 1) fbo.setWriteBuffer(1);
		if (l == 0) {
			glEnableDepth();
			glClearFramebuffer(view.backColor());
		} else {
			glEnable(GL_DEPTH_TEST);
			glDepthMask(GL_FALSE);
			glDepthFunc(GL_EQUAL);
			glClearFramebuffer(Qt::black, false);
			view.camera()->apply(view.aspect);
		}
		// rp.cam_offset_matrix = view.camera()->offsetMatrix();
		// rp.prepare();
		setupLights(l, 8);
		renderObjects(GLObjectBase::Solid, l, nullptr, true, view.isLightEnabled(), view.isFogEnabled());
		renderObjects(GLObjectBase::Transparent, l, nullptr, true, true, view.isFogEnabled());
		if (passes > 1) {
			glSetLightEnabled(false);
			glSetCapEnabled(GL_BLEND);
			glBlendFunc(GL_ONE, GL_ONE);
			view.glReleaseTextures();
			glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(1));
			glDisableDepth();
			fbo.setWriteBuffer(0);
			glDrawQuad();
		}
	}
	if (view.isFeatureEnabled(QGLView::qglFXAA) || passes > 1) {
		fbo.release();
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, fbo.colorTexture());
		glSetLightEnabled(false);
		glSetCapEnabled(GL_BLEND, false);
		glDisableDepth();
		if (view.isFeatureEnabled(QGLView::qglFXAA)) {
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			shader_fxaa->bind();
			shader_fxaa->setUniformValue("dt", QVector2D(1.f / view.width(), 1.f / view.height()));
			glDrawQuad();
			shader_fxaa->release();
		} else {
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glDrawQuad();
		}
	}
}
