diff --git a/qglengine/renderer.cpp b/qglengine/renderer.cpp index 4656f89..89ebad8 100644 --- a/qglengine/renderer.cpp +++ b/qglengine/renderer.cpp @@ -29,7 +29,7 @@ using namespace QGLEngineShaders; Renderer::Renderer(QGLView * view_): RendererBase(view_), fbo_ds (view_, QVector() << GL_RGBA16F << GL_RGBA32F << GL_RGBA16F << GL_RGBA16F << GL_RGBA16F), - fbo_out (view_, 6, false, GL_RGBA16F), + fbo_out (view_, obrBuffersCount, false, GL_RGBA16F), rend_mat(this), rend_service(this), rend_selection(this), tone_proc(this) { quad = Primitive::plane(2., 2.); cam_light = new Light(); @@ -157,8 +157,10 @@ void Renderer::initShaders() { prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i); } if (bindShader(srFinalPass, &prog)) { - for (int i = 0; i < 5; ++i) - prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i); + prog->setUniformValue("tex_s_0", 0); + prog->setUniformValue("tex_s_1", 1); + prog->setUniformValue("tex_t_0", 2); + prog->setUniformValue("tex_t_1", 3); } if (bindShader(srGeometryPass, &prog)) { setUniformMaps(prog); @@ -223,6 +225,29 @@ void Renderer::renderObjects(Scene & scene, RenderPass pass) { } +void Renderer::renderLight(int first_wr_buff) { + QOpenGLShaderProgram * prog = 0; + Camera * cam = view->camera(); + fbo_ds.bindColorTextures(); + fbo_out.bind(); + //int ri = 1, wi = 0; + typedef QPair PassPair; + QVector passes; + passes << PassPair(srLightOmniPass, Light::Omni) << PassPair(srLightSpotPass, Light::Cone); + foreach (PassPair pass, passes) { + if (bindShader(pass.first, &prog)) { + setUniformCamera(prog, cam); + setUniformViewCorners(prog, cam); + prog->setUniformValue("lights_start", lights_start[pass.second]); + prog->setUniformValue("lights_count", cur_lights[pass.second].size()); + fbo_out.setWriteBuffer(first_wr_buff + pass.second); + glClearFramebuffer(Qt::black, false); + renderQuad(prog, quad, cam); + } + } +} + + void Renderer::renderScene() { initShaders(); QOpenGLExtraFunctions * f = view; @@ -248,14 +273,14 @@ void Renderer::renderScene() { } /// lights - QMap> ll = scene.lights_used; + cur_lights = scene.lights_used; if (is_camera_light) { - ll[Light::Omni] << cam_light; + cur_lights[Light::Omni] << cam_light; cam_light->setPos(cam->pos()); } if (scene.lights_changed) { scene.lights_changed = false; - reloadLightsParameters(ll); + reloadLightsParameters(cur_lights); } reloadLightsPositions(cam); @@ -264,7 +289,7 @@ void Renderer::renderScene() { rend_selection.renderSelection(scene); } - /// geometry pass + /// solid geometry pass fbo_ds.bind(); glEnableDepth(); glClearFramebuffer(); @@ -273,36 +298,35 @@ void Renderer::renderScene() { textures_empty.bind(f, tarEmpty); textures_maps .bind(f, tarMaps ); renderObjects(scene, rpSolid); + } + fbo_ds.release(); + + /// lighting passes + renderLight(obrSolidOmni); + + /// transparent geometry pass + fbo_ds.bind(); + glEnableDepth(); + glClearFramebuffer(Qt::black, false); + if (bindShader(srGeometryPass, &prog)) { renderObjects(scene, rpTransparent); } fbo_ds.release(); /// lighting passes - fbo_ds.bindColorTextures(); - fbo_out.bind(); - //int ri = 1, wi = 0; - typedef QPair PassPair; - QVector passes; - passes << PassPair(srLightOmniPass, Light::Omni) << PassPair(srLightSpotPass, Light::Cone); - foreach (PassPair pass, passes) { - if (bindShader(pass.first, &prog)) { - setUniformCamera(prog, cam); - setUniformViewCorners(prog, cam); - prog->setUniformValue("lights_start", lights_start[pass.second]); - prog->setUniformValue("lights_count", ll[pass.second].size()); - fbo_out.setWriteBuffer(obrSolidOmni + pass.second); - glClearFramebuffer(Qt::black, false); - renderQuad(prog, quad, cam); - } - } + renderLight(obrTransparentOmni); /// blending layers if (bindShader(srFinalPass, &prog)) { - fbo_out.bindColorTexture(obrSolidOmni, 0); - fbo_out.bindColorTexture(obrSolidSpot, 1); + fbo_out.bindColorTexture(obrSolidOmni , 0); + fbo_out.bindColorTexture(obrSolidSpot , 1); + fbo_out.bindColorTexture(obrTransparentOmni, 2); + fbo_out.bindColorTexture(obrTransparentSpot, 3); fbo_out.setWriteBuffer(obrSum); renderQuad(prog, quad); } + + /// tonemapping if (tone_proc.process()) fbo_out.bind(); if (bindShader(srTonemapPass, &prog)) { diff --git a/qglengine/renderer.h b/qglengine/renderer.h index 0e75903..2071625 100644 --- a/qglengine/renderer.h +++ b/qglengine/renderer.h @@ -65,6 +65,10 @@ class Renderer: public RendererBase { obrSum, obrSolidOmni, obrSolidSpot, + obrTransparentOmni, + obrTransparentSpot, + + obrBuffersCount, }; public: @@ -85,6 +89,7 @@ protected: void fillObjectsBuffer(const ObjectBaseList & ol, RenderPass pass); void reloadObjects(); void renderObjects(Scene & scene, RenderPass pass); + void renderLight(int first_wr_buff); bool bindShader(ShaderRole role, QOpenGLShaderProgram ** ret = 0); bool bindShader(QOpenGLShaderProgram * sp); @@ -118,6 +123,7 @@ private: QMatrix3x3 nm; QVector4D corner_dirs[4]; QVector hcontent; + QMap> cur_lights; };