/* 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 . */ #include "renderer_deferred_shading.h" RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo(5, true, GL_RGBA16F) { shader_fxaa = shader_ds_0 = shader_ds_1 = 0; } void RendererDeferredShading::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; if (passes < 1) passes = 1; fbo.bind(); int buffs[] = {0, 1, 2}; fbo.setWriteBuffers(buffs); glClearFramebuffer(QColor(0, 0, 0, 0)); //glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glDepthMask(GL_TRUE); shader_ds_0->bind(); shader_ds_0->setUniformValue("t0", 0); shader_ds_0->setUniformValue("t1", 1); shader_ds_0->setUniformValue("t2", 2); shader_ds_0->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height())); renderObjects(GLObjectBase::Solid, 0, 0, true, false, false); //glReleaseShaders(); //fbo.release(); glSetLightEnabled(false); glDisable(GL_BLEND); //glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); shader_ds_1->bind(); shader_ds_1->setUniformValue("t0", 0); shader_ds_1->setUniformValue("t1", 1); shader_ds_1->setUniformValue("t2", 2); shader_ds_1->setUniformValue("back_color", view.backColor()); shader_ds_1->setUniformValue("mat", pm.inverted()); shader_ds_1->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height())); fbo.setWriteBuffer(3); fbo.bindColorTextures(); glClearFramebuffer(Qt::black, false); QVector lpos; GLfloat glmvm[16]; glGetFloatv(GL_MODELVIEW_MATRIX, glmvm); //glResetAllTransforms(); for (int l = 0; l < passes; ++l) { fbo.setWriteBuffer(4 - l % 2); shader_ds_1->setUniformValue("tb", 3 + l % 2); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(glmvm); setupLights(l, 8); shader_ds_1->setUniformValue("lightsCount", cplc); glDrawQuad(); //renderObjects(GLObjectBase::Solid, l, 0, true, true, view.isFogEnabled()); //renderObjects(GLObjectBase::Transparent, l, 0, true, true, view.isFogEnabled()); glFinish(); } fbo.release(); glReleaseShaders(); glActiveTextureChannel(0); glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(3 + passes % 2)); if (view.isFXAAEnabled()) { 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. / view.viewport()->width(), 1. / view.viewport()->height())); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } glDrawQuad(); if (view.isFXAAEnabled()) shader_fxaa->release(); } void RendererDeferredShading::reloadShaders() { if (shader_fxaa == 0) shader_fxaa = new QGLShaderProgram(view.context()); if (shader_ds_0 == 0) shader_ds_0 = new QGLShaderProgram(view.context()); if (shader_ds_1 == 0) shader_ds_1 = new QGLShaderProgram(view.context()); //if (shader_ds_0 == 0) shader_ds_0 = new QGLShaderProgram(view.context()); loadShaders(shader_fxaa, "FXAA", "shaders"); loadShaders(shader_ds_0, "dsl_pass_0", "shaders"); loadShaders(shader_ds_1, "dsl_pass_1", "shaders"); } void RendererDeferredShading::setupShadersTextures(GLObjectBase & object, GLRendererBase::RenderingParameters & rp) { shader_ds_0->setUniformValue("has_diffuse", object.material().diffuse.bitmap_id != 0); shader_ds_0->setUniformValue("has_bump", object.material().bump.bitmap_id != 0); shader_ds_0->setUniformValue("has_height", object.material().relief.bitmap_id != 0); shader_ds_0->setUniformValue("bump_scale", object.material().bump_scale); shader_ds_0->setUniformValue("height_scale", object.material().relief_scale); }