| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- #include "anki/renderer/Is.h"
- #include "anki/renderer/Renderer.h"
- #include "anki/scene/Camera.h"
- #include "anki/scene/Light.h"
- #include "anki/scene/PointLight.h"
- #include "anki/scene/SpotLight.h"
- #include "anki/resource/LightRsrc.h"
- #include "anki/core/App.h"
- #include "anki/resource/LightRsrc.h"
- #include "anki/renderer/Sm.h"
- #include "anki/renderer/Smo.h"
- #include "anki/scene/Scene.h"
- #include <boost/lexical_cast.hpp>
- #include <boost/foreach.hpp>
- #include <boost/array.hpp>
- #define BLEND_ENABLE true
- namespace anki {
- //==============================================================================
- // 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 ANKI_EXCEPTION("Cannot create deferred shading illumination "
- "stage FBO") << e;
- }
- }
- //==============================================================================
- // 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 ANKI_EXCEPTION("Cannot create deferred shading "
- "illumination stage additional FBO") << e;
- }
- }
- //==============================================================================
- // init =
- //==============================================================================
- void Is::init(const RendererInitializer& initializer)
- {
- // init passes
- smo.init(initializer);
- sm.init(initializer);
- // load the shaders
- ambientPassSProg.load("shaders/IsAp.glsl");
- // point light
- pointLightSProg.load(ShaderProgram::createSrcCodeToCache(
- "shaders/IsLpGeneric.glsl", "#define POINT_LIGHT_ENABLED\n").c_str());
- // spot light no shadow
- spotLightNoShadowSProg.load(ShaderProgram::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.load(ShaderProgram::createSrcCodeToCache(
- "shaders/IsLpGeneric.glsl", pps.c_str()).c_str());
- // init the rest
- initCopy();
- initFbo();
- }
- //==============================================================================
- // ambientPass =
- //==============================================================================
- void Is::ambientPass(const Vec3& color)
- {
- GlStateMachineSingleton::get().enable(GL_BLEND, false);
- // set the shader
- ambientPassSProg->bind();
- // set the uniforms
- ambientPassSProg->getUniformVariableByName("ambientCol").set(&color);
- ambientPassSProg->getUniformVariableByName("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::get().enable(GL_DEPTH_TEST, false);
- // shader prog
- const ShaderProgram& shader = *pointLightSProg; // ensure the const-ness
- shader.bind();
- shader.getUniformVariableByName("msNormalFai").set(
- r.getMs().getNormalFai(), 0);
- shader.getUniformVariableByName("msDiffuseFai").set(
- r.getMs().getDiffuseFai(), 1);
- shader.getUniformVariableByName("msSpecularFai").set(
- r.getMs().getSpecularFai(), 2);
- shader.getUniformVariableByName("msDepthFai").set(
- r.getMs().getDepthFai(), 3);
- shader.getUniformVariableByName("planes").set(&r.getPlanes());
- shader.getUniformVariableByName("limitsOfNearPlane").set(
- &r.getLimitsOfNearPlane());
- shader.getUniformVariableByName("limitsOfNearPlane2").set(
- &r.getLimitsOfNearPlane2());
- float zNear = cam.getZNear();
- shader.getUniformVariableByName("zNear").set(&zNear);
- const Vec3& origin = light.getWorldTransform().getOrigin();
- Vec3 lightPosEyeSpace = origin.getTransformed(cam.getViewMatrix());
- shader.getUniformVariableByName("lightPos").set(&lightPosEyeSpace);
- shader.getUniformVariableByName("lightRadius").set(light.getRadius());
- shader.getUniformVariableByName("lightDiffuseCol").set(
- &light.getDiffuseColor());
- shader.getUniformVariableByName("lightSpecularCol").set(
- &light.getSpecularColor());
- // render quad
- r.drawQuad();
- }
- //==============================================================================
- // spotLightPass =
- //==============================================================================
- void Is::spotLightPass(const SpotLight& light)
- {
- const Camera& cam = r.getCamera();
- bool withShadow = light.getCastShadow() && sm.getEnabled() &&
- (light.getVisibleMsRenderableNodes().size() > 0);
- // shadow mapping
- if(withShadow)
- {
- Vec3 zAxis = light.getWorldTransform().getRotation().getColumn(2);
- LineSegment seg(light.getWorldTransform().getOrigin(),
- -zAxis * light.getCamera().getZFar());
- const 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::get().enable(GL_BLEND, BLEND_ENABLE);
- glBlendFunc(GL_ONE, GL_ONE);
- GlStateMachineSingleton::get().enable(GL_DEPTH_TEST, false);
- GlStateMachineSingleton::get().setViewport(0, 0,
- r.getWidth(), r.getHeight());
- }
- // stencil optimization
- smo.run(light);
- GlStateMachineSingleton::get().enable(GL_DEPTH_TEST, false);
- // set the texture
- //light.getTexture().setRepeat(false);
- // shader prog
- const ShaderProgram* shdr;
- if(withShadow)
- {
- shdr = spotLightShadowSProg.get();
- }
- else
- {
- shdr = spotLightNoShadowSProg.get();
- }
- shdr->bind();
- // bind the FAIs
- const Ms& ms = r.getMs();
- shdr->getUniformVariableByName("msNormalFai").set(ms.getNormalFai(), 0);
- shdr->getUniformVariableByName("msDiffuseFai").set(ms.getDiffuseFai(), 1);
- shdr->getUniformVariableByName("msSpecularFai").set(ms.getSpecularFai(), 2);
- shdr->getUniformVariableByName("msDepthFai").set(ms.getDepthFai(), 3);
- // the ???
- shdr->getUniformVariableByName("planes").set(&r.getPlanes());
- shdr->getUniformVariableByName("limitsOfNearPlane").set(
- &r.getLimitsOfNearPlane());
- shdr->getUniformVariableByName("limitsOfNearPlane2").set(
- &r.getLimitsOfNearPlane2());
- float zNear = cam.getZNear();
- shdr->getUniformVariableByName("zNear").set(&zNear);
- // the light params
- const Vec3& origin = light.getWorldTransform().getOrigin();
- Vec3 lightPosEyeSpace = origin.getTransformed(cam.getViewMatrix());
- shdr->getUniformVariableByName("lightPos").set(&lightPosEyeSpace);
- float tmp = light.getDistance();
- shdr->getUniformVariableByName("lightRadius").set(&tmp);
- shdr->getUniformVariableByName("lightDiffuseCol").set(
- &light.getDiffuseColor());
- shdr->getUniformVariableByName("lightSpecularCol").set(
- &light.getSpecularColor());
- shdr->getUniformVariableByName("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->getUniformVariableByName("texProjectionMat").set(&texProjectionMat);
- // the shadowmap
- if(light.getCastShadow() && sm.getEnabled())
- {
- shdr->getUniformVariableByName("shadowMap").set(sm.getShadowMap(), 5);
- float smSize = sm.getShadowMap().getWidth();
- shdr->getUniformVariableByName("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::get().setViewport(0, 0,
- r.getWidth(), r.getHeight());
- // Copy
- if(r.getFramesNum() % 2 == 0)
- {
- copyDepth();
- }
- // FBO
- fbo.bind();
- // ambient pass
- GlStateMachineSingleton::get().enable(GL_DEPTH_TEST, false);
- ambientPass(SceneSingleton::get().getAmbientColor());
- // light passes
- GlStateMachineSingleton::get().enable(GL_BLEND, BLEND_ENABLE);
- glBlendFunc(GL_ONE, GL_ONE);
- GlStateMachineSingleton::get().enable(GL_STENCIL_TEST);
- // for all lights
- BOOST_FOREACH(const PointLight* light,
- r.getCamera().getVisiblePointLights())
- {
- /*if(light->getVisibleMsRenderableNodes().size() == 0)
- {
- continue;
- }*/
- pointLightPass(*light);
- }
- BOOST_FOREACH(const SpotLight* light, r.getCamera().getVisibleSpotLights())
- {
- /*if(light->getVisibleMsRenderableNodes() == 0)
- {
- continue;
- }*/
- spotLightPass(*light);
- }
-
- GlStateMachineSingleton::get().disable(GL_STENCIL_TEST);
- // FBO
- //fbo.unbind();
- ANKI_CHECK_GL_ERROR();
- }
- } // end namespace
|