| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- #include <boost/lexical_cast.hpp>
- #include <boost/foreach.hpp>
- #include <boost/array.hpp>
- #include "Is.h"
- #include "Renderer.h"
- #include "Scene/Camera.h"
- #include "Scene/Light.h"
- #include "Scene/PointLight.h"
- #include "Scene/SpotLight.h"
- #include "Resources/LightRsrc.h"
- #include "Core/App.h"
- #include "Resources/LightRsrc.h"
- #include "Sm.h"
- #include "Smo.h"
- #include "Scene/Scene.h"
- namespace R {
- //==============================================================================
- // Constructor =
- //==============================================================================
- Is::Is(Renderer& r_):
- RenderingPass(r_),
- sm(r_),
- smo(r_)
- {}
- //==============================================================================
- // initFbo =
- //==============================================================================
- void Is::initFbo()
- {
- try
- {
- // create FBO
- fbo.create();
- fbo.bind();
- // inform in what buffers we draw
- fbo.setNumOfColorAttachements(1);
- // create the FAI
- Renderer::createFai(r.getWidth(), r.getHeight(), GL_RGB, GL_RGB,
- GL_FLOAT, fai);
- // attach
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, fai.getGlId(), 0);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_TEXTURE_2D, copyMsDepthFai.getGlId(), 0);
- // test if success
- fbo.checkIfGood();
- // unbind
- fbo.unbind();
- }
- catch(std::exception& e)
- {
- throw EXCEPTION("Cannot create deferred shading illumination "
- "stage FBO: " + e.what());
- }
- }
- //==============================================================================
- // initCopy =
- //==============================================================================
- void Is::initCopy()
- {
- try
- {
- // Read
- readFbo.create();
- readFbo.bind();
- readFbo.setNumOfColorAttachements(0);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_TEXTURE_2D, r.getMs().getDepthFai().getGlId(), 0);
- readFbo.unbind();
- // Write
- Renderer::createFai(r.getWidth(), r.getHeight(), GL_DEPTH24_STENCIL8,
- GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, copyMsDepthFai);
- writeFbo.create();
- writeFbo.bind();
- writeFbo.setNumOfColorAttachements(0);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_TEXTURE_2D, copyMsDepthFai.getGlId(), 0);
- writeFbo.unbind();
- }
- catch(std::exception& e)
- {
- throw EXCEPTION("Cannot create deferred shading illumination stage "
- "additional FBO: " + e.what());
- }
- }
- //==============================================================================
- // init =
- //==============================================================================
- void Is::init(const RendererInitializer& initializer)
- {
- // init passes
- smo.init(initializer);
- sm.init(initializer);
- // load the shaders
- ambientPassSProg.loadRsrc("shaders/IsAp.glsl");
- // point light
- pointLightSProg.loadRsrc(ShaderProg::createSrcCodeToCache(
- "shaders/IsLpGeneric.glsl", "#define POINT_LIGHT_ENABLED\n").c_str());
- // spot light no shadow
- spotLightNoShadowSProg.loadRsrc(ShaderProg::createSrcCodeToCache(
- "shaders/IsLpGeneric.glsl", "#define SPOT_LIGHT_ENABLED\n").c_str());
- // spot light w/t shadow
- std::string pps = std::string("#define SPOT_LIGHT_ENABLED\n"
- "#define SHADOW_ENABLED\n");
- if(sm.isPcfEnabled())
- {
- pps += "#define PCF_ENABLED\n";
- }
- spotLightShadowSProg.loadRsrc(ShaderProg::createSrcCodeToCache(
- "shaders/IsLpGeneric.glsl", pps.c_str()).c_str());
- // init the rest
- initCopy();
- initFbo();
- }
- //==============================================================================
- // ambientPass =
- //==============================================================================
- void Is::ambientPass(const Vec3& color)
- {
- GlStateMachineSingleton::getInstance().enable(GL_BLEND, false);
- // set the shader
- ambientPassSProg->bind();
- // set the uniforms
- ambientPassSProg->findUniVar("ambientCol")->set(&color);
- ambientPassSProg->findUniVar("sceneColMap")->set(r.getMs().getDiffuseFai(),
- 0);
- // Draw quad
- r.drawQuad();
- }
- //==============================================================================
- // pointLightPass =
- //==============================================================================
- void Is::pointLightPass(const PointLight& light)
- {
- const Camera& cam = r.getCamera();
- // stencil optimization
- smo.run(light);
- GlStateMachineSingleton::getInstance().enable(GL_DEPTH_TEST, false);
- // shader prog
- const ShaderProg& shader = *pointLightSProg; // ensure the const-ness
- shader.bind();
- shader.findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 0);
- shader.findUniVar("msDiffuseFai")->set(r.getMs().getDiffuseFai(), 1);
- shader.findUniVar("msSpecularFai")->set(r.getMs().getSpecularFai(), 2);
- shader.findUniVar("msDepthFai")->set(r.getMs().getDepthFai(), 3);
- shader.findUniVar("planes")->set(&r.getPlanes());
- shader.findUniVar("limitsOfNearPlane")->set(&r.getLimitsOfNearPlane());
- shader.findUniVar("limitsOfNearPlane2")->set(&r.getLimitsOfNearPlane2());
- float zNear = cam.getZNear();
- shader.findUniVar("zNear")->set(&zNear);
- const Vec3& origin = light.getWorldTransform().getOrigin();
- Vec3 lightPosEyeSpace = origin.getTransformed(cam.getViewMatrix());
- shader.findUniVar("lightPos")->set(&lightPosEyeSpace);
- shader.findUniVar("lightRadius")->set(&light.getRadius());
- shader.findUniVar("lightDiffuseCol")->set(&light.getDiffuseCol());
- shader.findUniVar("lightSpecularCol")->set(&light.getSpecularCol());
- // render quad
- r.drawQuad();
- }
- //==============================================================================
- // spotLightPass =
- //==============================================================================
- void Is::spotLightPass(const SpotLight& light)
- {
- const Camera& cam = r.getCamera();
- // shadow mapping
- if(light.castsShadow() && sm.isEnabled())
- {
- Vec3 zAxis = light.getWorldTransform().getRotation().getColumn(2);
- Col::LineSegment seg(light.getWorldTransform().getOrigin(),
- -zAxis * light.getCamera().getZFar());
- const Col::Plane& plane = cam.getWSpaceFrustumPlane(Camera::FP_NEAR);
- float dist = seg.testPlane(plane);
- sm.run(light, dist);
- // restore the IS FBO
- fbo.bind();
- // and restore blending and depth test
- GlStateMachineSingleton::getInstance().enable(GL_BLEND, true);
- glBlendFunc(GL_ONE, GL_ONE);
- GlStateMachineSingleton::getInstance().enable(GL_DEPTH_TEST, false);
- GlStateMachineSingleton::getInstance().setViewport(0, 0,
- r.getWidth(), r.getHeight());
- }
- // stencil optimization
- smo.run(light);
- GlStateMachineSingleton::getInstance().enable(GL_DEPTH_TEST, false);
- // set the texture
- //light.getTexture().setRepeat(false);
- // shader prog
- const ShaderProg* shdr;
- if(light.castsShadow() && sm.isEnabled())
- {
- shdr = spotLightShadowSProg.get();
- }
- else
- {
- shdr = spotLightNoShadowSProg.get();
- }
- shdr->bind();
- // bind the FAIs
- shdr->findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 0);
- shdr->findUniVar("msDiffuseFai")->set(r.getMs().getDiffuseFai(), 1);
- shdr->findUniVar("msSpecularFai")->set(r.getMs().getSpecularFai(), 2);
- shdr->findUniVar("msDepthFai")->set(r.getMs().getDepthFai(), 3);
- // the ???
- shdr->findUniVar("planes")->set(&r.getPlanes());
- shdr->findUniVar("limitsOfNearPlane")->set(&r.getLimitsOfNearPlane());
- shdr->findUniVar("limitsOfNearPlane2")->set(&r.getLimitsOfNearPlane2());
- float zNear = cam.getZNear();
- shdr->findUniVar("zNear")->set(&zNear);
- // the light params
- const Vec3& origin = light.getWorldTransform().getOrigin();
- Vec3 lightPosEyeSpace = origin.getTransformed(cam.getViewMatrix());
- shdr->findUniVar("lightPos")->set(&lightPosEyeSpace);
- float tmp = light.getDistance();
- shdr->findUniVar("lightRadius")->set(&tmp);
- shdr->findUniVar("lightDiffuseCol")->set(&light.getDiffuseCol());
- shdr->findUniVar("lightSpecularCol")->set(&light.getSpecularCol());
- shdr->findUniVar("lightTex")->set(light.getTexture(), 4);
- // set texture matrix for texture & shadowmap projection
- // Bias * P_light * V_light * inv(V_cam)
- static Mat4 biasMat4(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5,
- 0.5, 0.0, 0.0, 0.0, 1.0);
- Mat4 texProjectionMat;
- texProjectionMat = biasMat4 * light.getCamera().getProjectionMatrix() *
- Mat4::combineTransformations(light.getCamera().getViewMatrix(),
- Mat4(cam.getWorldTransform()));
- shdr->findUniVar("texProjectionMat")->set(&texProjectionMat);
- // the shadowmap
- if(light.castsShadow() && sm.isEnabled())
- {
- shdr->findUniVar("shadowMap")->set(sm.getShadowMap(), 5);
- float smSize = sm.getShadowMap().getWidth();
- shdr->findUniVar("shadowMapSize")->set(&smSize);
- }
- // render quad
- r.drawQuad();
- }
- //==============================================================================
- // copyDepth =
- //==============================================================================
- void Is::copyDepth()
- {
- readFbo.bind(GL_READ_FRAMEBUFFER);
- writeFbo.bind(GL_DRAW_FRAMEBUFFER);
- glBlitFramebuffer(0, 0, r.getWidth(), r.getHeight(), 0, 0, r.getWidth(),
- r.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
- }
- //==============================================================================
- // run =
- //==============================================================================
- void Is::run()
- {
- // OGL stuff
- GlStateMachineSingleton::getInstance().setViewport(0, 0,
- r.getWidth(), r.getHeight());
- // Copy
- if(r.getFramesNum() % 2 == 0)
- {
- copyDepth();
- }
- // FBO
- fbo.bind();
- // ambient pass
- GlStateMachineSingleton::getInstance().enable(GL_DEPTH_TEST, false);
- ambientPass(SceneSingleton::getInstance().getAmbientCol());
- // light passes
- GlStateMachineSingleton::getInstance().enable(GL_BLEND, true);
- glBlendFunc(GL_ONE, GL_ONE);
- GlStateMachineSingleton::getInstance().enable(GL_STENCIL_TEST);
- // for all lights
- BOOST_FOREACH(const PointLight* light,
- r.getCamera().getVisiblePointLights())
- {
- pointLightPass(*light);
- }
-
- BOOST_FOREACH(const SpotLight* light, r.getCamera().getVisibleSpotLights())
- {
- spotLightPass(*light);
- }
-
- GlStateMachineSingleton::getInstance().disable(GL_STENCIL_TEST);
- // FBO
- //fbo.unbind();
- ON_GL_FAIL_THROW_EXCEPTION();
- }
- } // end namespace
|