Moved m_post_processing attribute from IrrDriver to ShaderBasedRenderer, and removed some getter/setter functions

This commit is contained in:
Elderme 2016-01-17 13:42:06 +01:00
parent 76453afc49
commit bff0a98708
14 changed files with 535 additions and 441 deletions

View File

@ -60,6 +60,8 @@ public:
virtual void onLoadWorld() = 0; virtual void onLoadWorld() = 0;
virtual void onUnloadWorld() = 0; virtual void onUnloadWorld() = 0;
virtual void reset() {}
virtual void giveBoost(unsigned int cam_index) {}
virtual void addSkyBox(const std::vector<irr::video::ITexture*> &texture, virtual void addSkyBox(const std::vector<irr::video::ITexture*> &texture,
const std::vector<irr::video::ITexture*> &spherical_harmonics_textures) {} const std::vector<irr::video::ITexture*> &spherical_harmonics_textures) {}

View File

@ -157,7 +157,8 @@ void AbstractGeometryPasses::prepareShadowRendering(const FrameBuffer& shadow_fr
} }
void AbstractGeometryPasses::shadowPostProcessing(const ShadowMatrices& shadow_matrices, void AbstractGeometryPasses::shadowPostProcessing(const ShadowMatrices& shadow_matrices,
const FrameBuffer& shadow_framebuffer) const const FrameBuffer& shadow_framebuffer,
const PostProcessing* post_processing) const
{ {
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SHADOW_POSTPROCESS)); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SHADOW_POSTPROCESS));
@ -168,7 +169,7 @@ void AbstractGeometryPasses::shadowPostProcessing(const ShadowMatrices& shadow_m
for (unsigned i = 0; i < 2; i++) for (unsigned i = 0; i < 2; i++)
{ {
irr_driver->getPostProcessing()->renderGaussian6BlurLayer( post_processing->renderGaussian6BlurLayer(
shadow_framebuffer, i, shadow_framebuffer, i,
2.f * shadow_scales[0].first / shadow_scales[i].first, 2.f * shadow_scales[0].first / shadow_scales[i].first,
2.f * shadow_scales[0].second / shadow_scales[i].second); 2.f * shadow_scales[0].second / shadow_scales[i].second);
@ -183,7 +184,8 @@ void AbstractGeometryPasses::glowPostProcessing(const FrameBuffer& glow_framebuf
const FrameBuffer& half_framebuffer, const FrameBuffer& half_framebuffer,
const FrameBuffer& quarter_framebuffer, const FrameBuffer& quarter_framebuffer,
const FrameBuffer& color_framebuffer, const FrameBuffer& color_framebuffer,
GLuint quarter_render_target) const GLuint quarter_render_target,
const PostProcessing* post_processing) const
{ {
// To half // To half
FrameBuffer::Blit(glow_framebuffer, half_framebuffer, GL_COLOR_BUFFER_BIT, GL_LINEAR); FrameBuffer::Blit(glow_framebuffer, half_framebuffer, GL_COLOR_BUFFER_BIT, GL_LINEAR);
@ -198,7 +200,7 @@ void AbstractGeometryPasses::glowPostProcessing(const FrameBuffer& glow_framebuf
glStencilFunc(GL_EQUAL, 0, ~0); glStencilFunc(GL_EQUAL, 0, ~0);
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
color_framebuffer.bind(); color_framebuffer.bind();
irr_driver->getPostProcessing()->renderGlow(quarter_render_target);//TODO post_processing->renderGlow(quarter_render_target);//TODO
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
} }
@ -262,7 +264,7 @@ void renderTransparenPass(const std::vector<RenderGeometry::TexUnit> &TexUnits,
} // renderTransparenPass } // renderTransparenPass
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void AbstractGeometryPasses::renderTransparent(const DrawCalls& draw_calls, unsigned render_target) void AbstractGeometryPasses::renderTransparent(const DrawCalls& draw_calls, unsigned render_target, const PostProcessing* post_processing)
{ {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
@ -390,9 +392,9 @@ void AbstractGeometryPasses::renderTransparent(const DrawCalls& draw_calls, unsi
irr_driver->getFBO(FBO_COLORS).bind(); irr_driver->getFBO(FBO_COLORS).bind();
glStencilFunc(GL_EQUAL, 1, 0xFF); glStencilFunc(GL_EQUAL, 1, 0xFF);
irr_driver->getPostProcessing()->renderPassThrough(render_target, post_processing->renderPassThrough(render_target,
irr_driver->getFBO(FBO_COLORS).getWidth(), irr_driver->getFBO(FBO_COLORS).getWidth(),
irr_driver->getFBO(FBO_COLORS).getHeight()); irr_driver->getFBO(FBO_COLORS).getHeight());
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
} // renderTransparent } // renderTransparent

View File

@ -40,14 +40,16 @@ protected:
void prepareShadowRendering(const FrameBuffer& shadow_framebuffer) const; void prepareShadowRendering(const FrameBuffer& shadow_framebuffer) const;
void shadowPostProcessing(const ShadowMatrices& shadow_matrices, void shadowPostProcessing(const ShadowMatrices& shadow_matrices,
const FrameBuffer& shadow_framebuffer) const; const FrameBuffer& shadow_framebuffer,
const PostProcessing* post_processing) const;
//TODO: move it in ShaderBasedRenderer //TODO: move it in ShaderBasedRenderer
void glowPostProcessing(const FrameBuffer& glow_framebuffer, void glowPostProcessing(const FrameBuffer& glow_framebuffer,
const FrameBuffer& half_framebuffer, const FrameBuffer& half_framebuffer,
const FrameBuffer& quater_framebuffer, const FrameBuffer& quater_framebuffer,
const FrameBuffer& color_framebuffer, const FrameBuffer& color_framebuffer,
GLuint quarter_render_target) const; GLuint quarter_render_target,
const PostProcessing* post_processing) const;
public: public:
AbstractGeometryPasses(); AbstractGeometryPasses();
@ -67,14 +69,17 @@ public:
const FrameBuffer& half_framebuffer, const FrameBuffer& half_framebuffer,
const FrameBuffer& quarter_framebuffer, const FrameBuffer& quarter_framebuffer,
const FrameBuffer& color_framebuffer, const FrameBuffer& color_framebuffer,
GLuint quarter_render_target ) const = 0; GLuint quarter_render_target,
const PostProcessing* post_processing ) const = 0;
void renderTransparent(const DrawCalls& draw_calls, void renderTransparent(const DrawCalls& draw_calls,
unsigned render_target); unsigned render_target,
const PostProcessing* post_processing);
virtual void renderShadows(const DrawCalls& draw_calls, virtual void renderShadows(const DrawCalls& draw_calls,
const ShadowMatrices& shadow_matrices, const ShadowMatrices& shadow_matrices,
const FrameBuffer& shadow_framebuffer) const = 0; const FrameBuffer& shadow_framebuffer,
const PostProcessing* post_processing) const = 0;
virtual void renderReflectiveShadowMap(const DrawCalls& draw_calls, virtual void renderReflectiveShadowMap(const DrawCalls& draw_calls,
@ -123,7 +128,8 @@ public:
const FrameBuffer& half_framebuffer, const FrameBuffer& half_framebuffer,
const FrameBuffer& quarter_framebuffer, const FrameBuffer& quarter_framebuffer,
const FrameBuffer& color_framebuffer, const FrameBuffer& color_framebuffer,
GLuint quarter_render_target ) const GLuint quarter_render_target,
const PostProcessing* post_processing) const
{ {
irr_driver->getSceneManager()->setCurrentRendertime(scene::ESNRP_SOLID); irr_driver->getSceneManager()->setCurrentRendertime(scene::ESNRP_SOLID);
glow_framebuffer.bind(); glow_framebuffer.bind();
@ -147,14 +153,16 @@ public:
glowPostProcessing(glow_framebuffer, half_framebuffer, glowPostProcessing(glow_framebuffer, half_framebuffer,
quarter_framebuffer, color_framebuffer, quarter_framebuffer, color_framebuffer,
quarter_render_target); quarter_render_target,
post_processing);
} }
void renderShadows(const DrawCalls& draw_calls, void renderShadows(const DrawCalls& draw_calls,
const ShadowMatrices& shadow_matrices, const ShadowMatrices& shadow_matrices,
const FrameBuffer& shadow_framebuffer) const const FrameBuffer& shadow_framebuffer,
const PostProcessing* post_processing) const
{ {
prepareShadowRendering(shadow_framebuffer); prepareShadowRendering(shadow_framebuffer);
@ -167,7 +175,7 @@ public:
glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_POLYGON_OFFSET_FILL);
if (CVS->isESMEnabled()) if (CVS->isESMEnabled())
shadowPostProcessing(shadow_matrices, shadow_framebuffer); shadowPostProcessing(shadow_matrices, shadow_framebuffer, post_processing);
} }

View File

@ -29,7 +29,6 @@
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/particle_kind_manager.hpp" #include "graphics/particle_kind_manager.hpp"
#include "graphics/per_camera_node.hpp" #include "graphics/per_camera_node.hpp"
#include "graphics/post_processing.hpp"
#include "graphics/referee.hpp" #include "graphics/referee.hpp"
#include "graphics/render_target.hpp" #include "graphics/render_target.hpp"
#include "graphics/shader_based_renderer.hpp" #include "graphics/shader_based_renderer.hpp"
@ -138,19 +137,6 @@ IrrDriver::IrrDriver()
*/ */
IrrDriver::~IrrDriver() IrrDriver::~IrrDriver()
{ {
// Note that we can not simply delete m_post_processing here:
// m_post_processing uses a material that has a reference to
// m_post_processing (for a callback). So when the material is
// removed it will try to drop the ref count of its callback object,
// which is m_post_processing, and which was already deleted. So
// instead we just decrease the ref count here. When the material
// is deleted, it will trigger the actual deletion of
// PostProcessing when decreasing the refcount of its callback object.
if(m_post_processing)
{
// check if we createad the OpenGL device by calling initDevice()
m_post_processing->drop();
}
assert(m_device != NULL); assert(m_device != NULL);
m_device->drop(); m_device->drop();
@ -170,7 +156,7 @@ IrrDriver::~IrrDriver()
*/ */
void IrrDriver::reset() void IrrDriver::reset()
{ {
if (CVS->isGLSL()) m_post_processing->reset(); m_renderer->reset();
} // reset } // reset
void IrrDriver::setPhase(STKRenderingPass p) void IrrDriver::setPhase(STKRenderingPass p)
@ -642,9 +628,6 @@ void IrrDriver::initDevice()
material2D.AntiAliasing=video::EAAM_FULL_BASIC; material2D.AntiAliasing=video::EAAM_FULL_BASIC;
//m_video_driver->enableMaterial2D(); //m_video_driver->enableMaterial2D();
// Initialize post-processing if supported
m_post_processing = new PostProcessing(m_video_driver);
// set cursor visible by default (what's the default is not too clearly documented, // set cursor visible by default (what's the default is not too clearly documented,
// so let's decide ourselves...) // so let's decide ourselves...)
m_device->getCursorControl()->setVisible(true); m_device->getCursorControl()->setVisible(true);
@ -2427,7 +2410,6 @@ void IrrDriver::clearLights()
} // clearLights } // clearLights
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
GLuint IrrDriver::getRenderTargetTexture(TypeRTT which) GLuint IrrDriver::getRenderTargetTexture(TypeRTT which)
{ {
return m_renderer->getRTT()->getRenderTarget(which); return m_renderer->getRTT()->getRenderTarget(which);

View File

@ -66,7 +66,6 @@ class AbstractKart;
class AbstractRenderer; class AbstractRenderer;
class Camera; class Camera;
class PerCameraNode; class PerCameraNode;
class PostProcessing;
class LightNode; class LightNode;
class ShadowImportance; class ShadowImportance;
class ShadowMatrices; class ShadowMatrices;
@ -102,8 +101,6 @@ private:
video::IVideoDriver *m_video_driver; video::IVideoDriver *m_video_driver;
/** Irrlicht race font. */ /** Irrlicht race font. */
gui::IGUIFont *m_race_font; gui::IGUIFont *m_race_font;
/** Post-processing. */
PostProcessing *m_post_processing;
/** Renderer. */ /** Renderer. */
AbstractRenderer *m_renderer; AbstractRenderer *m_renderer;
@ -392,8 +389,8 @@ public:
* application. Value in msec. */ * application. Value in msec. */
unsigned int getRealTime() {return m_device->getTimer()->getRealTime(); } unsigned int getRealTime() {return m_device->getTimer()->getRealTime(); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a pointer to the post processing object. */ /** Use motion blur for a short time */
inline PostProcessing* getPostProcessing() {return m_post_processing;} void giveBoost(unsigned int cam_index) { m_renderer->giveBoost(cam_index);}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
inline core::vector3df getWind() {return m_wind->getWind();} inline core::vector3df getWind() {return m_wind->getWind();}

View File

@ -228,6 +228,80 @@ public:
} // NVWorkaroundRadianceHintsConstructionShader } // NVWorkaroundRadianceHintsConstructionShader
}; // NVWorkaroundRadianceHintsConstructionShader }; // NVWorkaroundRadianceHintsConstructionShader
// ============================================================================
class GlobalIlluminationReconstructionShader
: public TextureShader<GlobalIlluminationReconstructionShader, 5,
core::matrix4, core::matrix4, core::vector3df >
{
public:
GlobalIlluminationReconstructionShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "utils/decodeNormal.frag",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "gi.frag");
assignUniforms("rh_matrix", "inv_rh_matrix", "extents");
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED,
1, "dtex", ST_NEAREST_FILTERED,
2, "SHR", ST_VOLUME_LINEAR_FILTERED,
3, "SHG", ST_VOLUME_LINEAR_FILTERED,
4, "SHB", ST_VOLUME_LINEAR_FILTERED);
} // GlobalIlluminationReconstructionShader
// ------------------------------------------------------------------------
void render(const core::matrix4 &rh_matrix,
const core::vector3df &rh_extend,
const FrameBuffer &framebuffer,
GLuint normal_depth_texture,
GLuint depth_stencil_texture)
{
core::matrix4 inv_rh_matrix;
rh_matrix.getInverse(inv_rh_matrix);
glDisable(GL_DEPTH_TEST);
setTextureUnits(normal_depth_texture,
depth_stencil_texture,
framebuffer.getRTT()[0], framebuffer.getRTT()[1], framebuffer.getRTT()[2]);
drawFullScreenEffect(rh_matrix, inv_rh_matrix, rh_extend);
} // render
}; // GlobalIlluminationReconstructionShader
// ============================================================================
class IBLShader : public TextureShader<IBLShader, 3>
{
public:
IBLShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "utils/decodeNormal.frag",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "utils/DiffuseIBL.frag",
GL_FRAGMENT_SHADER, "utils/SpecularIBL.frag",
GL_FRAGMENT_SHADER, "IBL.frag");
assignUniforms();
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED,
1, "dtex", ST_NEAREST_FILTERED,
2, "probe", ST_TRILINEAR_CUBEMAP);
} // IBLShader
}; // IBLShader
// ============================================================================
class DegradedIBLShader : public TextureShader<DegradedIBLShader, 1>
{
public:
DegradedIBLShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "utils/decodeNormal.frag",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "utils/DiffuseIBL.frag",
GL_FRAGMENT_SHADER, "utils/SpecularIBL.frag",
GL_FRAGMENT_SHADER, "degraded_ibl.frag");
assignUniforms();
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED);
} // DegradedIBLShader
}; // DegradedIBLShader
// ============================================================================ // ============================================================================
class ShadowedSunLightShaderPCF : public TextureShader<ShadowedSunLightShaderPCF, class ShadowedSunLightShaderPCF : public TextureShader<ShadowedSunLightShaderPCF,
3, float, float, float, 3, float, float, float,
@ -305,6 +379,42 @@ public:
} // render } // render
}; // ShadowedSunLightShaderESM }; // ShadowedSunLightShaderESM
// ============================================================================
class SunLightShader : public TextureShader<SunLightShader, 2,
core::vector3df, video::SColorf>
{
public:
SunLightShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "utils/decodeNormal.frag",
GL_FRAGMENT_SHADER, "utils/SpecularBRDF.frag",
GL_FRAGMENT_SHADER, "utils/DiffuseBRDF.frag",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "utils/SunMRP.frag",
GL_FRAGMENT_SHADER, "sunlight.frag");
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED,
1, "dtex", ST_NEAREST_FILTERED);
assignUniforms("direction", "col");
} // SunLightShader
// ------------------------------------------------------------------------
void render(const core::vector3df &direction, const video::SColorf &col,
GLuint normal_depth_texture,
GLuint depth_stencil_texture)
{
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
setTextureUnits(normal_depth_texture,
depth_stencil_texture);
drawFullScreenEffect(direction, col);
} // render
}; // SunLightShader
// ============================================================================ // ============================================================================
static void renderPointLights(unsigned count, static void renderPointLights(unsigned count,
GLuint normal_depth_rander_target, GLuint normal_depth_rander_target,
@ -331,6 +441,57 @@ static void renderPointLights(unsigned count,
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
} // renderPointLights } // renderPointLights
// ----------------------------------------------------------------------------
void LightingPasses::renderEnvMap(GLuint normal_depth_texture,
GLuint depth_stencil_texture,
GLuint specular_probe)
{
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
if (UserConfigParams::m_degraded_IBL)
{
DegradedIBLShader::getInstance()->use();
glBindVertexArray(SharedGPUObjects::getFullScreenQuadVAO());
DegradedIBLShader::getInstance()
->setTextureUnits(normal_depth_texture);
DegradedIBLShader::getInstance()->setUniforms();
}
else
{
IBLShader::getInstance()->use();
glBindVertexArray(SharedGPUObjects::getFullScreenQuadVAO());
IBLShader::getInstance()->setTextureUnits(
normal_depth_texture,
depth_stencil_texture,
specular_probe);
IBLShader::getInstance()->setUniforms();
}
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
} // renderEnvMap
// ----------------------------------------------------------------------------
void LightingPasses::renderSunlight(const core::vector3df &direction,
const video::SColorf &col,
GLuint normal_depth_texture,
GLuint depth_stencil_texture)
{
SunLightShader::getInstance()->render(direction, col,
normal_depth_texture,
depth_stencil_texture);
} // renderSunlight
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void LightingPasses::updateLightsInfo(scene::ICameraSceneNode * const camnode, void LightingPasses::updateLightsInfo(scene::ICameraSceneNode * const camnode,
float dt) float dt)
@ -416,7 +577,9 @@ void LightingPasses::updateLightsInfo(scene::ICameraSceneNode * const camnode,
void LightingPasses::renderGlobalIllumination( const ShadowMatrices& shadow_matrices, void LightingPasses::renderGlobalIllumination( const ShadowMatrices& shadow_matrices,
const FrameBuffer& radiance_hint_framebuffer, const FrameBuffer& radiance_hint_framebuffer,
const FrameBuffer& reflective_shadow_map_framebuffer, const FrameBuffer& reflective_shadow_map_framebuffer,
const FrameBuffer& diffuse_framebuffer) const FrameBuffer& diffuse_framebuffer,
GLuint normal_depth_texture,
GLuint depth_stencil_texture)
{ {
//Radiance hints //Radiance hints
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH)); ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH));
@ -462,28 +625,31 @@ void LightingPasses::renderGlobalIllumination( const ShadowMatrices& shadow_mat
{ {
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI)); ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
diffuse_framebuffer.bind(); diffuse_framebuffer.bind();
irr_driver->getPostProcessing()->renderGI( shadow_matrices.getRHMatrix(), GlobalIlluminationReconstructionShader::getInstance()
shadow_matrices.getRHExtend(), ->render(shadow_matrices.getRHMatrix(),
radiance_hint_framebuffer); shadow_matrices.getRHExtend(),
radiance_hint_framebuffer,
normal_depth_texture,
depth_stencil_texture);
} }
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void LightingPasses::renderLights( bool has_shadow, void LightingPasses::renderLights( bool has_shadow,
GLuint normal_depth_rander_target, GLuint normal_depth_texture,
GLuint depth_stencil_texture, GLuint depth_stencil_texture,
const FrameBuffer& shadow_framebuffer, const FrameBuffer& shadow_framebuffer,
const FrameBuffer& diffuse_specular_framebuffer, const FrameBuffer& diffuse_specular_framebuffer,
GLuint specular_probe) GLuint specular_probe)
{ {
PostProcessing *post_processing = irr_driver->getPostProcessing();
diffuse_specular_framebuffer.bind(); diffuse_specular_framebuffer.bind();
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
{ {
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP)); ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP));
post_processing->renderEnvMap(specular_probe); renderEnvMap(normal_depth_texture,
depth_stencil_texture,
specular_probe);
} }
// Render sunlight if and only if track supports shadow // Render sunlight if and only if track supports shadow
@ -500,27 +666,29 @@ void LightingPasses::renderLights( bool has_shadow,
if (CVS->isESMEnabled()) if (CVS->isESMEnabled())
{ {
ShadowedSunLightShaderESM::getInstance()->render(normal_depth_rander_target, ShadowedSunLightShaderESM::getInstance()->render(normal_depth_texture,
depth_stencil_texture, depth_stencil_texture,
shadow_framebuffer); shadow_framebuffer);
} }
else else
{ {
ShadowedSunLightShaderPCF::getInstance()->render(normal_depth_rander_target, ShadowedSunLightShaderPCF::getInstance()->render(normal_depth_texture,
depth_stencil_texture, depth_stencil_texture,
shadow_framebuffer); shadow_framebuffer);
} }
} }
else else
post_processing->renderSunlight(irr_driver->getSunDirection(), renderSunlight(irr_driver->getSunDirection(),
irr_driver->getSunColor()); irr_driver->getSunColor(),
normal_depth_texture,
depth_stencil_texture);
} }
//points lights //points lights
{ {
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_POINTLIGHTS)); ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_POINTLIGHTS));
renderPointLights(std::min(m_point_light_count, LightBaseClass::MAXLIGHT), renderPointLights(std::min(m_point_light_count, LightBaseClass::MAXLIGHT),
normal_depth_rander_target, normal_depth_texture,
depth_stencil_texture); depth_stencil_texture);
} }
} // renderLights } // renderLights
@ -548,10 +716,11 @@ void LightingPasses::renderAmbientScatter(GLuint depth_stencil_texture)
} // renderAmbientScatter } // renderAmbientScatter
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void LightingPasses::renderLightsScatter(const FrameBuffer& half1_framebuffer, void LightingPasses::renderLightsScatter(GLuint depth_stencil_texture,
const FrameBuffer& half1_framebuffer,
const FrameBuffer& half2_framebuffer, const FrameBuffer& half2_framebuffer,
const FrameBuffer& colors_framebuffer, const FrameBuffer& colors_framebuffer,
GLuint half1_render_target) const PostProcessing* post_processing)
{ {
half1_framebuffer.bind(); half1_framebuffer.bind();
glClearColor(0., 0., 0., 0.); glClearColor(0., 0., 0., 0.);
@ -579,23 +748,23 @@ void LightingPasses::renderLightsScatter(const FrameBuffer& half1_framebuffer,
glBindVertexArray(PointLightScatterShader::getInstance()->vao); glBindVertexArray(PointLightScatterShader::getInstance()->vao);
PointLightScatterShader::getInstance() PointLightScatterShader::getInstance()
->setTextureUnits(irr_driver->getDepthStencilTexture()); ->setTextureUnits(depth_stencil_texture);
PointLightScatterShader::getInstance() PointLightScatterShader::getInstance()
->setUniforms(1.f / (40.f * start), col2); ->setUniforms(1.f / (40.f * start), col2);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4,
std::min(m_point_light_count, LightBaseClass::MAXLIGHT)); std::min(m_point_light_count,
LightBaseClass::MAXLIGHT));
glDisable(GL_BLEND); glDisable(GL_BLEND);
PostProcessing *post_processing = irr_driver->getPostProcessing();
post_processing->renderGaussian6Blur(half1_framebuffer, post_processing->renderGaussian6Blur(half1_framebuffer,
half2_framebuffer, 5., 5.); half2_framebuffer, 5., 5.);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
irr_driver->getFBO(FBO_COLORS).bind(); colors_framebuffer.bind();
post_processing->renderPassThrough(half1_render_target, post_processing->renderPassThrough(half1_framebuffer.getRTT()[0],
colors_framebuffer.getWidth(), colors_framebuffer.getWidth(),
colors_framebuffer.getHeight()); colors_framebuffer.getHeight());
} // renderLightsScatter } // renderLightsScatter

View File

@ -21,11 +21,22 @@
#include "graphics/glwrap.hpp" #include "graphics/glwrap.hpp"
#include <irrlicht.h> #include <irrlicht.h>
class PostProcessing;
class LightingPasses class LightingPasses
{ {
private: private:
unsigned m_point_light_count; unsigned m_point_light_count;
void renderEnvMap(GLuint normal_depth_texture,
GLuint depth_stencil_texture,
GLuint specular_probe);
/** Generate diffuse and specular map */
void renderSunlight(const core::vector3df &direction,
const video::SColorf &col,
GLuint normal_depth_texture,
GLuint depth_stencil_texture);
public: public:
LightingPasses(): m_point_light_count(0){} LightingPasses(): m_point_light_count(0){}
@ -36,18 +47,21 @@ public:
void renderGlobalIllumination( const ShadowMatrices& shadow_matrices, void renderGlobalIllumination( const ShadowMatrices& shadow_matrices,
const FrameBuffer& radiance_hint_framebuffer, const FrameBuffer& radiance_hint_framebuffer,
const FrameBuffer& reflective_shadow_map_framebuffer, const FrameBuffer& reflective_shadow_map_framebuffer,
const FrameBuffer& diffuse_framebuffer); const FrameBuffer& diffuse_framebuffer,
GLuint normal_depth_texture,
GLuint depth_stencil_texture);
void renderLights( bool has_shadow, void renderLights( bool has_shadow,
GLuint normal_depth_rander_target, GLuint normal_depth_texture,
GLuint depth_stencil_texture, GLuint depth_stencil_texture,
const FrameBuffer& shadow_framebuffer, const FrameBuffer& shadow_framebuffer,
const FrameBuffer& diffuse_specular_framebuffer, const FrameBuffer& diffuse_specular_framebuffer,
GLuint specular_probe); GLuint specular_probe);
void renderAmbientScatter(GLuint depth_stencil_texture); void renderAmbientScatter(GLuint depth_stencil_texture);
void renderLightsScatter(const FrameBuffer& half1_framebuffer, void renderLightsScatter(GLuint depth_stencil_texture,
const FrameBuffer& half1_framebuffer,
const FrameBuffer& half2_framebuffer, const FrameBuffer& half2_framebuffer,
const FrameBuffer& colors_framebuffer, const FrameBuffer& colors_framebuffer,
GLuint half1_render_target); const PostProcessing* post_processing);

View File

@ -21,7 +21,6 @@
#include "graphics/callbacks.hpp" #include "graphics/callbacks.hpp"
#include "graphics/camera.hpp" #include "graphics/camera.hpp"
#include "graphics/central_settings.hpp" #include "graphics/central_settings.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/mlaa_areamap.hpp" #include "graphics/mlaa_areamap.hpp"
#include "graphics/render_target.hpp" #include "graphics/render_target.hpp"
@ -217,10 +216,11 @@ public:
1, "depth", ST_BILINEAR_CLAMPED_FILTERED); 1, "depth", ST_BILINEAR_CLAMPED_FILTERED);
} // Gaussian17TapHShader } // Gaussian17TapHShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(const FrameBuffer &fb, int width, int height) void render(const FrameBuffer &fb, const FrameBuffer &linear_depth,
int width, int height)
{ {
setTextureUnits(fb.getRTT()[0], setTextureUnits(fb.getRTT()[0],
irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0] ); linear_depth.getRTT()[0] );
drawFullScreenEffect(core::vector2df(1.0f/width, 1.0f/height)); drawFullScreenEffect(core::vector2df(1.0f/width, 1.0f/height));
} // render } // render
@ -243,12 +243,13 @@ public:
} // ComputeGaussian17TapHShader } // ComputeGaussian17TapHShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(const FrameBuffer &fb, const FrameBuffer &auxiliary, void render(const FrameBuffer &fb, const FrameBuffer &auxiliary,
const FrameBuffer &linear_depth,
int width, int height) int width, int height)
{ {
use(); use();
glBindSampler(m_dest_tu, 0); glBindSampler(m_dest_tu, 0);
setTextureUnits(fb.getRTT()[0], setTextureUnits(fb.getRTT()[0],
irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]); linear_depth.getRTT()[0]);
glBindImageTexture(m_dest_tu, auxiliary.getRTT()[0], 0, false, glBindImageTexture(m_dest_tu, auxiliary.getRTT()[0], 0, false,
0, GL_WRITE_ONLY, GL_R16F); 0, GL_WRITE_ONLY, GL_R16F);
setUniforms(core::vector2df(1.0f/width, 1.0f/height)); setUniforms(core::vector2df(1.0f/width, 1.0f/height));
@ -272,10 +273,11 @@ public:
1, "depth", ST_BILINEAR_CLAMPED_FILTERED); 1, "depth", ST_BILINEAR_CLAMPED_FILTERED);
} // Gaussian17TapVShader } // Gaussian17TapVShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(const FrameBuffer &auxiliary, int width, int height) void render(const FrameBuffer &auxiliary, const FrameBuffer &linear_depth,
int width, int height)
{ {
setTextureUnits(auxiliary.getRTT()[0], setTextureUnits(auxiliary.getRTT()[0],
irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]); linear_depth.getRTT()[0]);
drawFullScreenEffect(core::vector2df(1.0f/width, 1.0f/height)); drawFullScreenEffect(core::vector2df(1.0f/width, 1.0f/height));
} // render } // render
@ -298,13 +300,14 @@ public:
assignTextureUnit(m_dest_tu, "dest"); assignTextureUnit(m_dest_tu, "dest");
} // ComputeGaussian17TapVShader } // ComputeGaussian17TapVShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(const FrameBuffer &auxiliary, const FrameBuffer &fb, void render(const FrameBuffer &auxiliary, const FrameBuffer &fb,
const FrameBuffer &linear_depth,
int width, int height) int width, int height)
{ {
use(); use();
glBindSampler(m_dest_tu, 0); glBindSampler(m_dest_tu, 0);
setTextureUnits(auxiliary.getRTT()[0], setTextureUnits(auxiliary.getRTT()[0],
irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]); linear_depth.getRTT()[0]);
glBindImageTexture(m_dest_tu, fb.getRTT()[0], 0, false, 0, glBindImageTexture(m_dest_tu, fb.getRTT()[0], 0, false, 0,
GL_WRITE_ONLY, GL_R16F); GL_WRITE_ONLY, GL_R16F);
setUniforms(core::vector2df(1.0f/width, 1.0f/height)); setUniforms(core::vector2df(1.0f/width, 1.0f/height));
@ -354,11 +357,13 @@ public:
3, "tex_dust", ST_BILINEAR_FILTERED); 3, "tex_dust", ST_BILINEAR_FILTERED);
} // BloomBlendShader } // BloomBlendShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render() void render(GLuint render_target_bloom_128,
GLuint render_target_bloom_256,
GLuint render_target_bloom_512)
{ {
setTextureUnits(irr_driver->getRenderTargetTexture(RTT_BLOOM_128), setTextureUnits(render_target_bloom_128,
irr_driver->getRenderTargetTexture(RTT_BLOOM_256), render_target_bloom_256,
irr_driver->getRenderTargetTexture(RTT_BLOOM_512), render_target_bloom_512,
getTextureGLuint(lensDustTex)); getTextureGLuint(lensDustTex));
drawFullScreenEffect(); drawFullScreenEffect();
} // render } // render
@ -379,11 +384,13 @@ public:
2, "tex_512", ST_BILINEAR_FILTERED); 2, "tex_512", ST_BILINEAR_FILTERED);
} // LensBlendShader } // LensBlendShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render() void render(GLuint render_target_lens_128,
GLuint render_target_lens_256,
GLuint render_target_lens_512)
{ {
setTextureUnits(irr_driver->getRenderTargetTexture(RTT_LENS_128), setTextureUnits(render_target_lens_128,
irr_driver->getRenderTargetTexture(RTT_LENS_256), render_target_lens_256,
irr_driver->getRenderTargetTexture(RTT_LENS_512)); render_target_lens_512);
drawFullScreenEffect(); drawFullScreenEffect();
} // render } // render
@ -426,51 +433,15 @@ public:
1, "dtex", ST_NEAREST_FILTERED); 1, "dtex", ST_NEAREST_FILTERED);
} // DepthOfFieldShader } // DepthOfFieldShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(const FrameBuffer &fb, GLuint rtt) void render(const FrameBuffer &framebuffer, GLuint color_texture, GLuint depth_stencil_texture)
{ {
fb.bind(); framebuffer.bind();
setTextureUnits(rtt, irr_driver->getDepthStencilTexture()); setTextureUnits(color_texture, depth_stencil_texture);
drawFullScreenEffect(); drawFullScreenEffect();
} // render } // render
}; // DepthOfFieldShader }; // DepthOfFieldShader
// ============================================================================
class IBLShader : public TextureShader<IBLShader, 3>
{
public:
IBLShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "utils/decodeNormal.frag",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "utils/DiffuseIBL.frag",
GL_FRAGMENT_SHADER, "utils/SpecularIBL.frag",
GL_FRAGMENT_SHADER, "IBL.frag");
assignUniforms();
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED,
1, "dtex", ST_NEAREST_FILTERED,
2, "probe", ST_TRILINEAR_CUBEMAP);
} // IBLShader
}; // IBLShader
// ============================================================================
class DegradedIBLShader : public TextureShader<DegradedIBLShader, 1>
{
public:
DegradedIBLShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "utils/decodeNormal.frag",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "utils/DiffuseIBL.frag",
GL_FRAGMENT_SHADER, "utils/SpecularIBL.frag",
GL_FRAGMENT_SHADER, "degraded_ibl.frag");
assignUniforms();
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED);
} // DegradedIBLShader
}; // DegradedIBLShader
// ============================================================================ // ============================================================================
class RHDebug : public Shader<RHDebug, core::matrix4, core::vector3df> class RHDebug : public Shader<RHDebug, core::matrix4, core::vector3df>
{ {
@ -490,41 +461,6 @@ public:
} // RHDebug } // RHDebug
}; // RHDebug }; // RHDebug
// ============================================================================
class GlobalIlluminationReconstructionShader
: public TextureShader<GlobalIlluminationReconstructionShader, 5,
core::matrix4, core::matrix4, core::vector3df >
{
public:
GlobalIlluminationReconstructionShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "utils/decodeNormal.frag",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "gi.frag");
assignUniforms("rh_matrix", "inv_rh_matrix", "extents");
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED,
1, "dtex", ST_NEAREST_FILTERED,
2, "SHR", ST_VOLUME_LINEAR_FILTERED,
3, "SHG", ST_VOLUME_LINEAR_FILTERED,
4, "SHB", ST_VOLUME_LINEAR_FILTERED);
} // GlobalIlluminationReconstructionShader
// ------------------------------------------------------------------------
void render(const core::matrix4 &rh_matrix,
const core::vector3df &rh_extend, const FrameBuffer &fb)
{
core::matrix4 inv_rh_matrix;
rh_matrix.getInverse(inv_rh_matrix);
glDisable(GL_DEPTH_TEST);
setTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH),
irr_driver->getDepthStencilTexture(),
fb.getRTT()[0], fb.getRTT()[1], fb.getRTT()[2]);
drawFullScreenEffect(rh_matrix, inv_rh_matrix, rh_extend);
} // render
}; // GlobalIlluminationReconstructionShader
// ============================================================================ // ============================================================================
class PassThroughShader : public TextureShader<PassThroughShader, 1, int, int> class PassThroughShader : public TextureShader<PassThroughShader, 1, int, int>
{ {
@ -587,9 +523,9 @@ public:
assignSamplerNames(0, "texture", ST_BILINEAR_FILTERED); assignSamplerNames(0, "texture", ST_BILINEAR_FILTERED);
} // LinearizeDepthShader } // LinearizeDepthShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render() void render(GLuint depth_stencil_texture)
{ {
setTextureUnits(irr_driver->getDepthStencilTexture()); setTextureUnits(depth_stencil_texture);
scene::ICameraSceneNode *c = irr_driver->getSceneManager()->getActiveCamera(); scene::ICameraSceneNode *c = irr_driver->getSceneManager()->getActiveCamera();
drawFullScreenEffect(c->getNearValue(), c->getFarValue() ); drawFullScreenEffect(c->getNearValue(), c->getFarValue() );
@ -637,9 +573,9 @@ public:
assignSamplerNames(0, "dtex", ST_SEMI_TRILINEAR); assignSamplerNames(0, "dtex", ST_SEMI_TRILINEAR);
} // SSAOShader } // SSAOShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render() void render(GLuint render_target_linear_depth)
{ {
setTextureUnits(irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH)); setTextureUnits(render_target_linear_depth);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
drawFullScreenEffect(irr_driver->getSSAORadius(), drawFullScreenEffect(irr_driver->getSSAORadius(),
@ -666,9 +602,9 @@ public:
1, "dtex", ST_NEAREST_FILTERED); 1, "dtex", ST_NEAREST_FILTERED);
} // MotionBlurShader } // MotionBlurShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(const FrameBuffer &fb, float boost_time) void render(const FrameBuffer &fb, float boost_time, GLuint depth_stencil_texture)
{ {
setTextureUnits(fb.getRTT()[0], irr_driver->getDepthStencilTexture()); setTextureUnits(fb.getRTT()[0], depth_stencil_texture);
Camera *cam = Camera::getActiveCamera(); Camera *cam = Camera::getActiveCamera();
// Todo : use a previousPVMatrix per cam, not global // Todo : use a previousPVMatrix per cam, not global
drawFullScreenEffect(cam->getPreviousPVMatrix(), drawFullScreenEffect(cam->getPreviousPVMatrix(),
@ -753,10 +689,12 @@ public:
1, "areaMap", ST_NEAREST_FILTERED); 1, "areaMap", ST_NEAREST_FILTERED);
} // MLAABlendWeightSHader } // MLAABlendWeightSHader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(video::ITexture *area_map, const core::vector2df &pixel_size) void render(video::ITexture *area_map,
const core::vector2df &pixel_size,
GLuint rtt_mlaa_tmp)
{ {
use(); use();
setTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), setTextureUnits(rtt_mlaa_tmp,
getTextureGLuint(area_map)); getTextureGLuint(area_map));
drawFullScreenEffect(pixel_size); drawFullScreenEffect(pixel_size);
@ -777,49 +715,18 @@ public:
1, "colorMap", ST_NEAREST_FILTERED); 1, "colorMap", ST_NEAREST_FILTERED);
} // MLAAGatherSHader } // MLAAGatherSHader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(const core::vector2df &pixel_size) void render(const core::vector2df &pixel_size,
GLuint rtt_mlaa_blend,
GLuint rtt_mlaa_tmp)
{ {
use(); use();
setTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND), setTextureUnits(rtt_mlaa_blend,
irr_driver->getRenderTargetTexture(RTT_MLAA_TMP)); rtt_mlaa_tmp);
drawFullScreenEffect(pixel_size); drawFullScreenEffect(pixel_size);
} // render } // render
}; // MLAAGatherSHader }; // MLAAGatherSHader
// ============================================================================
class SunLightShader : public TextureShader<SunLightShader, 2,
core::vector3df, video::SColorf>
{
public:
SunLightShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "utils/decodeNormal.frag",
GL_FRAGMENT_SHADER, "utils/SpecularBRDF.frag",
GL_FRAGMENT_SHADER, "utils/DiffuseBRDF.frag",
GL_FRAGMENT_SHADER, "utils/getPosFromUVDepth.frag",
GL_FRAGMENT_SHADER, "utils/SunMRP.frag",
GL_FRAGMENT_SHADER, "sunlight.frag");
assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED,
1, "dtex", ST_NEAREST_FILTERED);
assignUniforms("direction", "col");
} // SunLightShader
// ------------------------------------------------------------------------
void render(const core::vector3df &direction, const video::SColorf &col)
{
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
setTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH),
irr_driver->getDepthStencilTexture());
drawFullScreenEffect(direction, col);
} // render
}; // SunLightShader
// ============================================================================ // ============================================================================
class LightningShader : public TextureShader<LightningShader, 1, class LightningShader : public TextureShader<LightningShader, 1,
core::vector3df> core::vector3df>
@ -1008,48 +915,11 @@ void PostProcessing::update(float dt)
} // update } // update
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static void renderBloom(GLuint in) void PostProcessing::renderBloom(GLuint in)
{ {
BloomShader::getInstance()->render(in); BloomShader::getInstance()->render(in);
} // renderBloom } // renderBloom
// ----------------------------------------------------------------------------
void PostProcessing::renderEnvMap(GLuint skybox)
{
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
if (UserConfigParams::m_degraded_IBL)
{
DegradedIBLShader::getInstance()->use();
glBindVertexArray(SharedGPUObjects::getFullScreenQuadVAO());
DegradedIBLShader::getInstance()
->setTextureUnits(irr_driver
->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH));
DegradedIBLShader::getInstance()->setUniforms();
}
else
{
IBLShader::getInstance()->use();
glBindVertexArray(SharedGPUObjects::getFullScreenQuadVAO());
IBLShader::getInstance()->setTextureUnits(
irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH),
irr_driver->getDepthStencilTexture(), skybox);
IBLShader::getInstance()->setUniforms();
}
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
} // renderEnvMap
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderRHDebug(unsigned SHR, unsigned SHG, unsigned SHB, void PostProcessing::renderRHDebug(unsigned SHR, unsigned SHG, unsigned SHB,
const core::matrix4 &rh_matrix, const core::matrix4 &rh_matrix,
@ -1068,23 +938,6 @@ void PostProcessing::renderRHDebug(unsigned SHR, unsigned SHG, unsigned SHB,
glDisable(GL_PROGRAM_POINT_SIZE); glDisable(GL_PROGRAM_POINT_SIZE);
} // renderRHDebug } // renderRHDebug
// ----------------------------------------------------------------------------
void PostProcessing::renderGI(const core::matrix4 &rh_matrix,
const core::vector3df &rh_extend,
const FrameBuffer &fb)
{
GlobalIlluminationReconstructionShader::getInstance()->render(rh_matrix,
rh_extend,
fb);
} // renderGI
// ----------------------------------------------------------------------------
void PostProcessing::renderSunlight(const core::vector3df &direction,
const video::SColorf &col)
{
SunLightShader::getInstance()->render(direction, col);
} // renderSunlight
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static std::vector<float> getGaussianWeight(float sigma, size_t count) static std::vector<float> getGaussianWeight(float sigma, size_t count)
{ {
@ -1109,7 +962,7 @@ static std::vector<float> getGaussianWeight(float sigma, size_t count)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderGaussian3Blur(const FrameBuffer &in_fbo, void PostProcessing::renderGaussian3Blur(const FrameBuffer &in_fbo,
const FrameBuffer &auxiliary) const FrameBuffer &auxiliary) const
{ {
assert(in_fbo.getWidth() == auxiliary.getWidth() && assert(in_fbo.getWidth() == auxiliary.getWidth() &&
in_fbo.getHeight() == auxiliary.getHeight()); in_fbo.getHeight() == auxiliary.getHeight());
@ -1130,7 +983,7 @@ void PostProcessing::renderGaussian3Blur(const FrameBuffer &in_fbo,
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderGaussian6BlurLayer(const FrameBuffer &in_fbo, void PostProcessing::renderGaussian6BlurLayer(const FrameBuffer &in_fbo,
size_t layer, float sigma_h, size_t layer, float sigma_h,
float sigma_v) float sigma_v) const
{ {
GLuint layer_tex; GLuint layer_tex;
glGenTextures(1, &layer_tex); glGenTextures(1, &layer_tex);
@ -1190,7 +1043,7 @@ void PostProcessing::renderGaussian6BlurLayer(const FrameBuffer &in_fbo,
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderGaussian6Blur(const FrameBuffer &in_fbo, void PostProcessing::renderGaussian6Blur(const FrameBuffer &in_fbo,
const FrameBuffer &auxiliary, float sigma_v, const FrameBuffer &auxiliary, float sigma_v,
float sigma_h) float sigma_h) const
{ {
assert(in_fbo.getWidth() == auxiliary.getWidth() && assert(in_fbo.getWidth() == auxiliary.getWidth() &&
in_fbo.getHeight() == auxiliary.getHeight()); in_fbo.getHeight() == auxiliary.getHeight());
@ -1246,7 +1099,7 @@ void PostProcessing::renderGaussian6Blur(const FrameBuffer &in_fbo,
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderHorizontalBlur(const FrameBuffer &in_fbo, void PostProcessing::renderHorizontalBlur(const FrameBuffer &in_fbo,
const FrameBuffer &auxiliary) const FrameBuffer &auxiliary) const
{ {
assert(in_fbo.getWidth() == auxiliary.getWidth() && assert(in_fbo.getWidth() == auxiliary.getWidth() &&
in_fbo.getHeight() == auxiliary.getHeight()); in_fbo.getHeight() == auxiliary.getHeight());
@ -1262,7 +1115,8 @@ void PostProcessing::renderHorizontalBlur(const FrameBuffer &in_fbo,
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo, void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
const FrameBuffer &auxiliary) const FrameBuffer &auxiliary,
const FrameBuffer &linear_depth) const
{ {
assert(in_fbo.getWidth() == auxiliary.getWidth() && assert(in_fbo.getWidth() == auxiliary.getWidth() &&
in_fbo.getHeight() == auxiliary.getHeight()); in_fbo.getHeight() == auxiliary.getHeight());
@ -1273,6 +1127,7 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
{ {
auxiliary.bind(); auxiliary.bind();
Gaussian17TapHShader::getInstance()->render(in_fbo, Gaussian17TapHShader::getInstance()->render(in_fbo,
linear_depth,
in_fbo.getWidth(), in_fbo.getWidth(),
in_fbo.getHeight()); in_fbo.getHeight());
} }
@ -1280,6 +1135,7 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
{ {
ComputeGaussian17TapHShader::getInstance()->render(in_fbo, ComputeGaussian17TapHShader::getInstance()->render(in_fbo,
auxiliary, auxiliary,
linear_depth,
in_fbo.getWidth(), in_fbo.getWidth(),
in_fbo.getHeight()); in_fbo.getHeight());
} }
@ -1291,6 +1147,7 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
{ {
in_fbo.bind(); in_fbo.bind();
Gaussian17TapVShader::getInstance()->render(auxiliary, Gaussian17TapVShader::getInstance()->render(auxiliary,
linear_depth,
in_fbo.getWidth(), in_fbo.getWidth(),
in_fbo.getHeight()); in_fbo.getHeight());
} }
@ -1298,6 +1155,7 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
{ {
ComputeGaussian17TapVShader::getInstance()->render(auxiliary, ComputeGaussian17TapVShader::getInstance()->render(auxiliary,
in_fbo, in_fbo,
linear_depth,
in_fbo.getWidth(), in_fbo.getWidth(),
in_fbo.getHeight()); in_fbo.getHeight());
} }
@ -1308,13 +1166,13 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderPassThrough(GLuint tex, unsigned width, void PostProcessing::renderPassThrough(GLuint tex, unsigned width,
unsigned height) unsigned height) const
{ {
PassThroughShader::getInstance()->render(tex, width, height); PassThroughShader::getInstance()->render(tex, width, height);
} // renderPassThrough } // renderPassThrough
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderTextureLayer(unsigned tex, unsigned layer) void PostProcessing::renderTextureLayer(unsigned tex, unsigned layer) const
{ {
LayerPassThroughShader::getInstance()->use(); LayerPassThroughShader::getInstance()->use();
LayerPassThroughShader::getInstance()->bindVertexArray(); LayerPassThroughShader::getInstance()->bindVertexArray();
@ -1328,27 +1186,30 @@ void PostProcessing::renderTextureLayer(unsigned tex, unsigned layer)
} // renderTextureLayer } // renderTextureLayer
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderGlow(unsigned tex) void PostProcessing::renderGlow(unsigned tex) const
{ {
GlowShader::getInstance()->render(tex); GlowShader::getInstance()->render(tex);
} // renderGlow } // renderGlow
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderSSAO() void PostProcessing::renderSSAO(const FrameBuffer& linear_depth_framebuffer,
const FrameBuffer& ssao_framebuffer,
GLuint depth_stencil_texture)
{ {
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND); glDisable(GL_BLEND);
// Generate linear depth buffer // Generate linear depth buffer
irr_driver->getFBO(FBO_LINEAR_DEPTH).bind(); linear_depth_framebuffer.bind();
LinearizeDepthShader::getInstance()->render(); LinearizeDepthShader::getInstance()->render(depth_stencil_texture);
irr_driver->getFBO(FBO_SSAO).bind(); ssao_framebuffer.bind();
SSAOShader::getInstance()->render(); SSAOShader::getInstance()->render(linear_depth_framebuffer.getRTT()[0]);
} // renderSSAO } // renderSSAO
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::renderMotionBlur(unsigned , const FrameBuffer &in_fbo, void PostProcessing::renderMotionBlur(unsigned , const FrameBuffer &in_fbo,
FrameBuffer &out_fbo) FrameBuffer &out_fbo,
GLuint depth_stencil_texture)
{ {
MotionBlurProvider * const cb = MotionBlurProvider * const cb =
(MotionBlurProvider *)Shaders::getCallback(ES_MOTIONBLUR); (MotionBlurProvider *)Shaders::getCallback(ES_MOTIONBLUR);
@ -1376,16 +1237,88 @@ void PostProcessing::renderMotionBlur(unsigned , const FrameBuffer &in_fbo,
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
float boost_time = cb->getBoostTime(cam->getIndex()) * 10; float boost_time = cb->getBoostTime(cam->getIndex()) * 10;
MotionBlurShader::getInstance()->render(in_fbo, boost_time); MotionBlurShader::getInstance()->render(in_fbo, boost_time, depth_stencil_texture);
} // renderMotionBlur } // renderMotionBlur
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static void renderDoF(const FrameBuffer &fbo, GLuint rtt) void PostProcessing::renderDoF(const FrameBuffer &framebuffer, GLuint color_texture, GLuint depth_stencil_texture)
{ {
DepthOfFieldShader::getInstance()->render(fbo, rtt); DepthOfFieldShader::getInstance()->render(framebuffer, color_texture, depth_stencil_texture);
} // renderDoF } // renderDoF
// ----------------------------------------------------------------------------
void PostProcessing::renderGodRays(scene::ICameraSceneNode * const camnode,
const FrameBuffer &fbo,
const FrameBuffer &quarter1_fbo,
const FrameBuffer &quarter2_fbo)
{
Track* track = World::getWorld()->getTrack();
glEnable(GL_DEPTH_TEST);
// Grab the sky
fbo.bind();
glClear(GL_COLOR_BUFFER_BIT);
// irr_driver->renderSkybox(camnode);
// Set the sun's color
const SColor col = track->getGodRaysColor();
// The sun interposer
STKMeshSceneNode *sun = irr_driver->getSunInterposer();
sun->setGlowColors(col);
sun->setPosition(track->getGodRaysPosition());
sun->updateAbsolutePosition();
irr_driver->setPhase(GLOW_PASS);
sun->render();
glDisable(GL_DEPTH_TEST);
// Fade to quarter
irr_driver->getFBO(FBO_QUARTER1).bind();
glViewport(0, 0, irr_driver->getActualScreenSize().Width / 4,
irr_driver->getActualScreenSize().Height / 4);
GodFadeShader::getInstance()->render(fbo.getRTT()[0], col);
// Blur
renderGaussian3Blur(quarter1_fbo, quarter2_fbo);
// Calculate the sun's position in texcoords
const core::vector3df pos = track->getGodRaysPosition();
float ndc[4];
core::matrix4 trans = camnode->getProjectionMatrix();
trans *= camnode->getViewMatrix();
trans.transformVect(ndc, pos);
const float texh =
m_vertices[0].v1.TCoords.Y - m_vertices[0].v0.TCoords.Y;
const float texw =
m_vertices[0].v3.TCoords.X - m_vertices[0].v0.TCoords.X;
const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw;
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
// Rays please
irr_driver->getFBO(FBO_QUARTER2).bind();
GodRayShader::getInstance()
->render(quarter1_fbo.getRTT()[0], core::vector2df(sunx, suny));
// Blur
renderGaussian3Blur(quarter2_fbo, quarter1_fbo);
// Blend
glEnable(GL_BLEND);
glBlendColor(0., 0., 0., track->getGodRaysOpacity());
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
fbo.bind();
renderPassThrough(quarter2_fbo.getRTT()[0], fbo.getWidth(), fbo.getHeight());
glDisable(GL_BLEND);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void PostProcessing::applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer, void PostProcessing::applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer,
const FrameBuffer& mlaa_blend_framebuffer, const FrameBuffer& mlaa_blend_framebuffer,
@ -1412,7 +1345,7 @@ void PostProcessing::applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer,
mlaa_blend_framebuffer.bind(); mlaa_blend_framebuffer.bind();
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
MLAABlendWeightSHader::getInstance()->render(m_areamap, PIXEL_SIZE); MLAABlendWeightSHader::getInstance()->render(m_areamap, PIXEL_SIZE, mlaa_tmp_framebuffer.getRTT()[0]);
// Blit in to tmp1 // Blit in to tmp1
FrameBuffer::Blit(mlaa_colors_framebuffer, FrameBuffer::Blit(mlaa_colors_framebuffer,
@ -1420,7 +1353,8 @@ void PostProcessing::applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer,
// Pass 3: gather // Pass 3: gather
mlaa_colors_framebuffer.bind(); mlaa_colors_framebuffer.bind();
MLAAGatherSHader::getInstance()->render(PIXEL_SIZE); MLAAGatherSHader::getInstance()
->render(PIXEL_SIZE, mlaa_blend_framebuffer.getRTT()[0], mlaa_tmp_framebuffer.getRTT()[0]);
// Done. // Done.
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
@ -1442,10 +1376,11 @@ void PostProcessing::renderLightning(core::vector3df intensity)
/** Render the post-processed scene */ /** Render the post-processed scene */
FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
bool isRace, bool isRace,
RTT *rtts,
GL3RenderTarget *specified_render_target) GL3RenderTarget *specified_render_target)
{ {
FrameBuffer *in_fbo = &irr_driver->getFBO(FBO_COLORS); FrameBuffer *in_fbo = &rtts->getFBO(FBO_COLORS);
FrameBuffer *out_fbo = &irr_driver->getFBO(FBO_TMP1_WITH_DS); FrameBuffer *out_fbo = &rtts->getFBO(FBO_TMP1_WITH_DS);
// Each effect uses these as named, and sets them up for the next effect. // Each effect uses these as named, and sets them up for the next effect.
// This allows chaining effects where some may be disabled. // This allows chaining effects where some may be disabled.
@ -1457,97 +1392,28 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
World *world = World::getWorld(); World *world = World::getWorld();
Physics *physics = world ? world->getPhysics() : NULL; Physics *physics = world ? world->getPhysics() : NULL;
if (isRace && UserConfigParams::m_dof && (physics == NULL || !physics->isDebug())) if (isRace && UserConfigParams::m_dof && (physics == NULL || !physics->isDebug()))
{ {
PROFILER_PUSH_CPU_MARKER("- DoF", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- DoF", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_DOF)); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_DOF));
renderDoF(*out_fbo, in_fbo->getRTT()[0]); renderDoF(*out_fbo, in_fbo->getRTT()[0], rtts->getDepthStencilTexture());
std::swap(in_fbo, out_fbo); std::swap(in_fbo, out_fbo);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }
bool hasgodrays = false;
if (World::getWorld() != NULL)
hasgodrays = World::getWorld()->getTrack()->hasGodRays();
if (isRace && UserConfigParams::m_light_shaft && hasgodrays)
{ {
PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GODRAYS)); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GODRAYS));
bool hasgodrays = false; renderGodRays(camnode, *out_fbo, rtts->getFBO(FBO_QUARTER1), rtts->getFBO(FBO_QUARTER2));
if (World::getWorld() != NULL)
hasgodrays = World::getWorld()->getTrack()->hasGodRays();
if (isRace && UserConfigParams::m_light_shaft && hasgodrays)
{
Track* track = World::getWorld()->getTrack();
glEnable(GL_DEPTH_TEST);
// Grab the sky
out_fbo->bind();
glClear(GL_COLOR_BUFFER_BIT);
// irr_driver->renderSkybox(camnode);
// Set the sun's color
const SColor col = track->getGodRaysColor();
// The sun interposer
STKMeshSceneNode *sun = irr_driver->getSunInterposer();
sun->setGlowColors(col);
sun->setPosition(track->getGodRaysPosition());
sun->updateAbsolutePosition();
irr_driver->setPhase(GLOW_PASS);
sun->render();
glDisable(GL_DEPTH_TEST);
// Fade to quarter
irr_driver->getFBO(FBO_QUARTER1).bind();
glViewport(0, 0, irr_driver->getActualScreenSize().Width / 4,
irr_driver->getActualScreenSize().Height / 4);
GodFadeShader::getInstance()->render(out_fbo->getRTT()[0], col);
// Blur
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER1),
irr_driver->getFBO(FBO_QUARTER2));
// Calculate the sun's position in texcoords
const core::vector3df pos = track->getGodRaysPosition();
float ndc[4];
core::matrix4 trans = camnode->getProjectionMatrix();
trans *= camnode->getViewMatrix();
trans.transformVect(ndc, pos);
const float texh =
m_vertices[0].v1.TCoords.Y - m_vertices[0].v0.TCoords.Y;
const float texw =
m_vertices[0].v3.TCoords.X - m_vertices[0].v0.TCoords.X;
const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw;
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
// Rays please
irr_driver->getFBO(FBO_QUARTER2).bind();
GodRayShader::getInstance()
->render(irr_driver->getRenderTargetTexture(RTT_QUARTER1),
core::vector2df(sunx, suny) );
// Blur
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER2),
irr_driver->getFBO(FBO_QUARTER1));
// Blend
glEnable(GL_BLEND);
glBlendColor(0., 0., 0., track->getGodRaysOpacity());
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
in_fbo->bind();
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER2),
in_fbo->getWidth(), in_fbo->getHeight());
glDisable(GL_BLEND);
}
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }
// Simulate camera defects from there // Simulate camera defects from there
{ {
PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_BLOOM)); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_BLOOM));
@ -1557,46 +1423,48 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
glClear(GL_STENCIL_BUFFER_BIT); glClear(GL_STENCIL_BUFFER_BIT);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
FrameBuffer::Blit(*in_fbo, irr_driver->getFBO(FBO_BLOOM_1024), FrameBuffer::Blit(*in_fbo, rtts->getFBO(FBO_BLOOM_1024),
GL_COLOR_BUFFER_BIT, GL_LINEAR); GL_COLOR_BUFFER_BIT, GL_LINEAR);
irr_driver->getFBO(FBO_BLOOM_512).bind(); rtts->getFBO(FBO_BLOOM_512).bind();
renderBloom(irr_driver->getRenderTargetTexture(RTT_BLOOM_1024)); renderBloom(rtts->getRenderTarget(RTT_BLOOM_1024));
// Downsample // Downsample
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512), FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_512),
irr_driver->getFBO(FBO_BLOOM_256), rtts->getFBO(FBO_BLOOM_256),
GL_COLOR_BUFFER_BIT, GL_LINEAR); GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256), FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_256),
irr_driver->getFBO(FBO_BLOOM_128), rtts->getFBO(FBO_BLOOM_128),
GL_COLOR_BUFFER_BIT, GL_LINEAR); GL_COLOR_BUFFER_BIT, GL_LINEAR);
// Copy for lens flare // Copy for lens flare
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512), FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_512),
irr_driver->getFBO(FBO_LENS_512), rtts->getFBO(FBO_LENS_512),
GL_COLOR_BUFFER_BIT, GL_LINEAR); GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256), FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_256),
irr_driver->getFBO(FBO_LENS_256), rtts->getFBO(FBO_LENS_256),
GL_COLOR_BUFFER_BIT, GL_LINEAR); GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_128), FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_128),
irr_driver->getFBO(FBO_LENS_128), rtts->getFBO(FBO_LENS_128),
GL_COLOR_BUFFER_BIT, GL_LINEAR); GL_COLOR_BUFFER_BIT, GL_LINEAR);
// Blur // Blur
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_512), renderGaussian6Blur(rtts->getFBO(FBO_BLOOM_512),
irr_driver->getFBO(FBO_TMP_512), 1., 1.); rtts->getFBO(FBO_TMP_512), 1., 1.);
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_256), renderGaussian6Blur(rtts->getFBO(FBO_BLOOM_256),
irr_driver->getFBO(FBO_TMP_256), 1., 1.); rtts->getFBO(FBO_TMP_256), 1., 1.);
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_128), renderGaussian6Blur(rtts->getFBO(FBO_BLOOM_128),
irr_driver->getFBO(FBO_TMP_128), 1., 1.); rtts->getFBO(FBO_TMP_128), 1., 1.);
renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_512), renderHorizontalBlur(rtts->getFBO(FBO_LENS_512),
irr_driver->getFBO(FBO_TMP_512)); rtts->getFBO(FBO_TMP_512));
renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_256), renderHorizontalBlur(rtts->getFBO(FBO_LENS_256),
irr_driver->getFBO(FBO_TMP_256)); rtts->getFBO(FBO_TMP_256));
renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_128), renderHorizontalBlur(rtts->getFBO(FBO_LENS_128),
irr_driver->getFBO(FBO_TMP_128)); rtts->getFBO(FBO_TMP_128));
// Additively blend on top of tmp1 // Additively blend on top of tmp1
@ -1605,8 +1473,14 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD); glBlendEquation(GL_FUNC_ADD);
BloomBlendShader::getInstance()->render(); BloomBlendShader::getInstance()
LensBlendShader::getInstance()->render(); ->render(rtts->getRenderTarget(RTT_BLOOM_128),
rtts->getRenderTarget(RTT_BLOOM_256),
rtts->getRenderTarget(RTT_BLOOM_512));
LensBlendShader::getInstance()
->render(rtts->getRenderTarget(RTT_LENS_128),
rtts->getRenderTarget(RTT_LENS_256),
rtts->getRenderTarget(RTT_LENS_512));
glDisable(GL_BLEND); glDisable(GL_BLEND);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@ -1634,7 +1508,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
if (isRace && UserConfigParams::m_motionblur && World::getWorld() && if (isRace && UserConfigParams::m_motionblur && World::getWorld() &&
cb->getBoostTime(Camera::getActiveCamera()->getIndex()) > 0.) // motion blur cb->getBoostTime(Camera::getActiveCamera()->getIndex()) > 0.) // motion blur
{ {
renderMotionBlur(0, *in_fbo, *out_fbo); renderMotionBlur(0, *in_fbo, *out_fbo, irr_driver->getDepthStencilTexture());
std::swap(in_fbo, out_fbo); std::swap(in_fbo, out_fbo);
} }
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
@ -1668,16 +1542,16 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
out_fbo->bind(); out_fbo->bind();
renderPassThrough(in_fbo->getRTT()[0], renderPassThrough(in_fbo->getRTT()[0],
out_fbo->getWidth(), out_fbo->getWidth(),
out_fbo->getHeight()); out_fbo->getHeight());
if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter. if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
{ {
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MLAA)); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MLAA));
applyMLAA(irr_driver->getFBO(FBO_MLAA_TMP), applyMLAA(rtts->getFBO(FBO_MLAA_TMP),
irr_driver->getFBO(FBO_MLAA_BLEND), rtts->getFBO(FBO_MLAA_BLEND),
*out_fbo); *out_fbo);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }

View File

@ -22,8 +22,8 @@
#include "S3DVertex.h" #include "S3DVertex.h"
#include "SMaterial.h" #include "SMaterial.h"
#include "graphics/camera.hpp" #include "graphics/camera.hpp"
#include "graphics/glwrap.hpp"
class FrameBuffer;
class GL3RenderTarget; class GL3RenderTarget;
#include <vector> #include <vector>
@ -75,47 +75,52 @@ public:
void begin(); void begin();
void update(float dt); void update(float dt);
/** Generate diffuse and specular map */ void renderBloom(GLuint in);
void renderSunlight(const core::vector3df &direction, void renderSSAO(const FrameBuffer& linear_depth_framebuffer,
const video::SColorf &col); const FrameBuffer& ssao_framebuffer,
GLuint depth_stencil_texture);
void renderSSAO();
void renderEnvMap(unsigned skycubemap);
void renderRHDebug(unsigned SHR, unsigned SHG, unsigned SHB, void renderRHDebug(unsigned SHR, unsigned SHG, unsigned SHB,
const core::matrix4 &rh_matrix, const core::matrix4 &rh_matrix,
const core::vector3df &rh_extend); const core::vector3df &rh_extend);
void renderGI(const core::matrix4 &rh_matrix,
const core::vector3df &rh_extend,
const FrameBuffer &fb);
/** Blur the in texture */ /** Blur the in texture */
void renderGaussian3Blur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary); void renderGaussian3Blur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary) const;
void renderGaussian6Blur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary, void renderGaussian6Blur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary,
float sigmaV, float sigmaH); float sigmaV, float sigmaH) const;
void renderHorizontalBlur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary); void renderHorizontalBlur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary) const;
void renderGaussian6BlurLayer(const FrameBuffer &in_fbo, size_t layer, void renderGaussian6BlurLayer(const FrameBuffer &in_fbo, size_t layer,
float sigmaH, float sigmaV); float sigmaH, float sigmaV) const;
void renderGaussian17TapBlur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary); void renderGaussian17TapBlur(const FrameBuffer &in_fbo,
const FrameBuffer &auxiliary,
const FrameBuffer &linear_depth) const;
/** Render tex. Used for blit/texture resize */ /** Render tex. Used for blit/texture resize */
void renderPassThrough(unsigned tex, unsigned width, unsigned height); void renderPassThrough(unsigned tex, unsigned width, unsigned height) const;
void renderTextureLayer(unsigned tex, unsigned layer); void renderTextureLayer(unsigned tex, unsigned layer) const;
void renderDoF(const FrameBuffer &framebuffer, GLuint color_texture, GLuint depth_stencil_texture);
void renderGodRays(scene::ICameraSceneNode * const camnode,
const FrameBuffer &in_fbo,
const FrameBuffer &quarter1_fbo,
const FrameBuffer &quarter2_fbo);
void applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer, void applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer,
const FrameBuffer& mlaa_blend_framebuffer, const FrameBuffer& mlaa_blend_framebuffer,
const FrameBuffer& mlaa_colors_framebuffer); const FrameBuffer& mlaa_colors_framebuffer);
void renderMotionBlur(unsigned cam, const FrameBuffer &in_fbo, void renderMotionBlur(unsigned cam, const FrameBuffer &in_fbo,
FrameBuffer &out_fbo); FrameBuffer &out_fbo,
void renderGlow(unsigned tex); GLuint depth_stencil_texture);
void renderGlow(unsigned tex) const;
void renderLightning(core::vector3df intensity); void renderLightning(core::vector3df intensity);
/** Render the post-processed scene */
FrameBuffer *render(scene::ICameraSceneNode * const camnode, bool isRace,
GL3RenderTarget *specified_render_target = NULL);
/** Use motion blur for a short time */ /** Use motion blur for a short time */
void giveBoost(unsigned int cam_index); void giveBoost(unsigned int cam_index);
/** Render the post-processed scene */
FrameBuffer *render(scene::ICameraSceneNode * const camnode, bool isRace,
RTT *rtts, GL3RenderTarget *specified_render_target = NULL);
}; // class PostProcessing }; // class PostProcessing
#endif // HEADER_POST_PROCESSING_HPP #endif // HEADER_POST_PROCESSING_HPP

View File

@ -211,13 +211,16 @@ void ShaderBasedRenderer::renderSSAO() const
m_rtts->getFBO(FBO_SSAO).bind(); m_rtts->getFBO(FBO_SSAO).bind();
glClearColor(1., 1., 1., 1.); glClearColor(1., 1., 1., 1.);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
irr_driver->getPostProcessing()->renderSSAO(); m_post_processing->renderSSAO(m_rtts->getFBO(FBO_LINEAR_DEPTH),
m_rtts->getFBO(FBO_SSAO),
m_rtts->getDepthStencilTexture());
// Blur it to reduce noise. // Blur it to reduce noise.
FrameBuffer::Blit(m_rtts->getFBO(FBO_SSAO), FrameBuffer::Blit(m_rtts->getFBO(FBO_SSAO),
m_rtts->getFBO(FBO_HALF1_R), m_rtts->getFBO(FBO_HALF1_R),
GL_COLOR_BUFFER_BIT, GL_LINEAR); GL_COLOR_BUFFER_BIT, GL_LINEAR);
irr_driver->getPostProcessing()->renderGaussian17TapBlur(m_rtts->getFBO(FBO_HALF1_R), m_post_processing->renderGaussian17TapBlur(m_rtts->getFBO(FBO_HALF1_R),
m_rtts->getFBO(FBO_HALF2_R)); m_rtts->getFBO(FBO_HALF2_R),
m_rtts->getFBO(FBO_LINEAR_DEPTH));
} // renderSSAO } // renderSSAO
@ -227,7 +230,6 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
bool hasShadow, bool hasShadow,
bool forceRTT) bool forceRTT)
{ {
PostProcessing *post_processing = irr_driver->getPostProcessing();
m_wind_dir = getWindDir(); //TODO m_wind_dir = getWindDir(); //TODO
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedGPUObjects::getViewProjectionMatricesUBO()); glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedGPUObjects::getViewProjectionMatricesUBO());
@ -247,7 +249,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
m_geometry_passes->renderShadows(m_draw_calls, m_geometry_passes->renderShadows(m_draw_calls,
m_shadow_matrices, m_shadow_matrices,
m_rtts->getShadowFrameBuffer()); m_rtts->getShadowFrameBuffer(),
m_post_processing);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
if (CVS->isGlobalIlluminationEnabled()) if (CVS->isGlobalIlluminationEnabled())
{ {
@ -312,7 +315,9 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
m_lighting_passes.renderGlobalIllumination( m_shadow_matrices, m_lighting_passes.renderGlobalIllumination( m_shadow_matrices,
m_rtts->getRadianceHintFrameBuffer(), m_rtts->getRadianceHintFrameBuffer(),
m_rtts->getReflectiveShadowMapFrameBuffer(), m_rtts->getReflectiveShadowMapFrameBuffer(),
m_rtts->getFBO(FBO_DIFFUSE)); m_rtts->getFBO(FBO_DIFFUSE),
m_rtts->getRenderTarget(RTT_NORMAL_AND_DEPTH),
m_rtts->getDepthStencilTexture());
} }
GLuint specular_probe; GLuint specular_probe;
@ -398,10 +403,11 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
{ {
PROFILER_PUSH_CPU_MARKER("- PointLight Scatter", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- PointLight Scatter", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_FOG)); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_FOG));
m_lighting_passes.renderLightsScatter(m_rtts->getFBO(FBO_HALF1), m_lighting_passes.renderLightsScatter(m_rtts->getDepthStencilTexture(),
m_rtts->getFBO(FBO_HALF1),
m_rtts->getFBO(FBO_HALF2), m_rtts->getFBO(FBO_HALF2),
m_rtts->getFBO(FBO_COLORS), m_rtts->getFBO(FBO_COLORS),
m_rtts->getRenderTarget(RTT_HALF1)); m_post_processing);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }
@ -409,20 +415,23 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
{ {
glDisable(GL_BLEND); glDisable(GL_BLEND);
m_rtts->getFBO(FBO_COLORS).bind(); m_rtts->getFBO(FBO_COLORS).bind();
post_processing->renderRHDebug(m_rtts->getRadianceHintFrameBuffer().getRTT()[0], m_post_processing->renderRHDebug(m_rtts->getRadianceHintFrameBuffer().getRTT()[0],
m_rtts->getRadianceHintFrameBuffer().getRTT()[1], m_rtts->getRadianceHintFrameBuffer().getRTT()[1],
m_rtts->getRadianceHintFrameBuffer().getRTT()[2], m_rtts->getRadianceHintFrameBuffer().getRTT()[2],
m_shadow_matrices.getRHMatrix(), m_shadow_matrices.getRHMatrix(),
m_shadow_matrices.getRHExtend()); m_shadow_matrices.getRHExtend());
} }
if (irr_driver->getGI()) if (irr_driver->getGI())
{ {
glDisable(GL_BLEND); glDisable(GL_BLEND);
m_rtts->getFBO(FBO_COLORS).bind(); m_rtts->getFBO(FBO_COLORS).bind();
post_processing->renderGI(m_shadow_matrices.getRHMatrix(), m_lighting_passes.renderGlobalIllumination(m_shadow_matrices,
m_shadow_matrices.getRHExtend(), m_rtts->getRadianceHintFrameBuffer(),
m_rtts->getRadianceHintFrameBuffer()); m_rtts->getReflectiveShadowMapFrameBuffer(),
m_rtts->getFBO(FBO_DIFFUSE),
m_rtts->getRenderTarget(RTT_NORMAL_AND_DEPTH),
m_rtts->getDepthStencilTexture());
} }
PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00); PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00);
@ -436,7 +445,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
m_rtts->getFBO(FBO_HALF1), m_rtts->getFBO(FBO_HALF1),
m_rtts->getFBO(FBO_QUARTER1), m_rtts->getFBO(FBO_QUARTER1),
m_rtts->getFBO(FBO_COLORS), m_rtts->getFBO(FBO_COLORS),
m_rtts->getRenderTarget(RTT_QUARTER1)); m_rtts->getRenderTarget(RTT_QUARTER1),
m_post_processing);
} // end glow } // end glow
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
@ -445,7 +455,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TRANSPARENT)); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TRANSPARENT));
m_geometry_passes->renderTransparent(m_draw_calls, m_geometry_passes->renderTransparent(m_draw_calls,
m_rtts->getRenderTarget(RTT_DISPLACE)); m_rtts->getRenderTarget(RTT_DISPLACE),
m_post_processing);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }
@ -483,7 +494,6 @@ void ShaderBasedRenderer::renderParticles()
// m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT); // m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
} }
void ShaderBasedRenderer::renderBoundingBoxes() void ShaderBasedRenderer::renderBoundingBoxes()
{ {
Shaders::ColoredLine *line = Shaders::ColoredLine::getInstance(); Shaders::ColoredLine *line = Shaders::ColoredLine::getInstance();
@ -547,8 +557,7 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
const core::recti &viewport = camera->getViewport(); const core::recti &viewport = camera->getViewport();
bool isRace = StateManager::get()->getGameState() == GUIEngine::GAME; bool isRace = StateManager::get()->getGameState() == GUIEngine::GAME;
PostProcessing * post_processing = irr_driver->getPostProcessing(); FrameBuffer *fbo = m_post_processing->render(camnode, isRace, m_rtts);
FrameBuffer *fbo = post_processing->render(camnode, isRace);
if (irr_driver->getNormals()) if (irr_driver->getNormals())
irr_driver->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); irr_driver->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
@ -556,24 +565,24 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
post_processing->renderPassThrough(m_rtts->getFBO(FBO_HALF1_R).getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); m_post_processing->renderPassThrough(m_rtts->getFBO(FBO_HALF1_R).getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
} }
else if (irr_driver->getRSM()) else if (irr_driver->getRSM())
{ {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y); glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
post_processing->renderPassThrough(m_rtts->getReflectiveShadowMapFrameBuffer().getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); m_post_processing->renderPassThrough(m_rtts->getReflectiveShadowMapFrameBuffer().getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
} }
else if (irr_driver->getShadowViz()) else if (irr_driver->getShadowViz())
{ {
m_shadow_matrices.renderShadowsDebug(m_rtts->getShadowFrameBuffer()); m_shadow_matrices.renderShadowsDebug(m_rtts->getShadowFrameBuffer(), m_post_processing);
} }
else else
{ {
glEnable(GL_FRAMEBUFFER_SRGB); glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
camera->activate(); camera->activate();
post_processing->renderPassThrough(fbo->getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); m_post_processing->renderPassThrough(fbo->getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_FRAMEBUFFER_SRGB);
} }
} }
@ -592,10 +601,26 @@ ShaderBasedRenderer::ShaderBasedRenderer()
m_geometry_passes = new GeometryPasses<IndirectDrawPolicy>(); m_geometry_passes = new GeometryPasses<IndirectDrawPolicy>();
else else
m_geometry_passes = new GeometryPasses<GL3DrawPolicy>(); m_geometry_passes = new GeometryPasses<GL3DrawPolicy>();
// Initialize post-processing if supported
m_post_processing = new PostProcessing(irr_driver->getVideoDriver());
} }
ShaderBasedRenderer::~ShaderBasedRenderer() ShaderBasedRenderer::~ShaderBasedRenderer()
{ {
// Note that we can not simply delete m_post_processing here:
// m_post_processing uses a material that has a reference to
// m_post_processing (for a callback). So when the material is
// removed it will try to drop the ref count of its callback object,
// which is m_post_processing, and which was already deleted. So
// instead we just decrease the ref count here. When the material
// is deleted, it will trigger the actual deletion of
// PostProcessing when decreasing the refcount of its callback object.
if(m_post_processing)
{
// check if we createad the OpenGL device by calling initDevice()
m_post_processing->drop();
}
delete m_geometry_passes; delete m_geometry_passes;
delete m_spherical_harmonics; delete m_spherical_harmonics;
delete m_skybox; delete m_skybox;
@ -619,6 +644,16 @@ void ShaderBasedRenderer::onUnloadWorld()
removeSkyBox(); removeSkyBox();
} }
void ShaderBasedRenderer::reset()
{
m_post_processing->reset();
}
void ShaderBasedRenderer::giveBoost(unsigned int cam_index)
{
m_post_processing->giveBoost(cam_index);
}
void ShaderBasedRenderer::addSkyBox(const std::vector<video::ITexture*> &texture, void ShaderBasedRenderer::addSkyBox(const std::vector<video::ITexture*> &texture,
const std::vector<video::ITexture*> &spherical_harmonics_textures) const std::vector<video::ITexture*> &spherical_harmonics_textures)
@ -687,7 +722,7 @@ void ShaderBasedRenderer::render(float dt)
// Start the RTT for post-processing. // Start the RTT for post-processing.
// We do this before beginScene() because we want to capture the glClear() // We do this before beginScene() because we want to capture the glClear()
// because of tracks that do not have skyboxes (generally add-on tracks) // because of tracks that do not have skyboxes (generally add-on tracks)
irr_driver->getPostProcessing()->begin(); m_post_processing->begin();
World *world = World::getWorld(); // Never NULL. World *world = World::getWorld(); // Never NULL.
Track *track = world->getTrack(); Track *track = world->getTrack();
@ -800,7 +835,7 @@ void ShaderBasedRenderer::render(float dt)
irr_driver->getVideoDriver()->endScene(); irr_driver->getVideoDriver()->endScene();
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
irr_driver->getPostProcessing()->update(dt); m_post_processing->update(dt);
removeItemsInGlowingList(); removeItemsInGlowingList();
} }
@ -838,7 +873,7 @@ void ShaderBasedRenderer::renderToTexture(GL3RenderTarget *render_target,
updateLightsInfo(camera, dt); updateLightsInfo(camera, dt);
uploadLightingData(); uploadLightingData();
renderScene(camera, dt, false, true); renderScene(camera, dt, false, true);
irr_driver->getPostProcessing()->render(camera, false, render_target); m_post_processing->render(camera, false, m_rtts, render_target);
// reset // reset
glViewport(0, 0, glViewport(0, 0,

View File

@ -28,8 +28,9 @@
#include <map> #include <map>
#include <string> #include <string>
class RenderTarget;
class GL3RenderTarget; class GL3RenderTarget;
class RenderTarget;
class PostProcessing;
class ShaderBasedRenderer: public AbstractRenderer class ShaderBasedRenderer: public AbstractRenderer
{ {
@ -42,6 +43,8 @@ private:
AbstractGeometryPasses *m_geometry_passes; AbstractGeometryPasses *m_geometry_passes;
LightingPasses m_lighting_passes; LightingPasses m_lighting_passes;
ShadowMatrices m_shadow_matrices; ShadowMatrices m_shadow_matrices;
/** Post-processing. */
PostProcessing *m_post_processing;
/** Static glowing things are loaded once per track. /** Static glowing things are loaded once per track.
* Glowing items can appear ordisappear each frame */ * Glowing items can appear ordisappear each frame */
@ -92,6 +95,8 @@ public:
void onLoadWorld() ; void onLoadWorld() ;
void onUnloadWorld(); void onUnloadWorld();
void reset() override;
void giveBoost(unsigned int cam_index) override;
void addSkyBox(const std::vector<irr::video::ITexture*> &texture, void addSkyBox(const std::vector<irr::video::ITexture*> &texture,
const std::vector<irr::video::ITexture*> &spherical_harmonics_textures) override; const std::vector<irr::video::ITexture*> &spherical_harmonics_textures) override;

View File

@ -475,12 +475,12 @@ void ShadowMatrices::renderWireFrameFrustrum(float *tmp, unsigned i)
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0); glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ShadowMatrices::renderShadowsDebug(const FrameBuffer &shadow_framebuffer) void ShadowMatrices::renderShadowsDebug(const FrameBuffer &shadow_framebuffer,
const PostProcessing *post_processing)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, UserConfigParams::m_height / 2, glViewport(0, UserConfigParams::m_height / 2,
UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
PostProcessing *post_processing = irr_driver->getPostProcessing();
post_processing->renderTextureLayer(shadow_framebuffer.getRTT()[0], 0); post_processing->renderTextureLayer(shadow_framebuffer.getRTT()[0], 0);
renderWireFrameFrustrum(m_shadows_cam[0], 0); renderWireFrameFrustrum(m_shadows_cam[0], 0);
glViewport(UserConfigParams::m_width / 2, UserConfigParams::m_height / 2, glViewport(UserConfigParams::m_width / 2, UserConfigParams::m_height / 2,

View File

@ -34,7 +34,7 @@ namespace irr
using namespace irr; using namespace irr;
class PostProcessing;
class ShadowMatrices class ShadowMatrices
{ {
@ -70,7 +70,8 @@ public:
GLuint depth_stencil_texture); GLuint depth_stencil_texture);
void addLight(const core::vector3df &pos); void addLight(const core::vector3df &pos);
void updateSunOrthoMatrices(); void updateSunOrthoMatrices();
void renderShadowsDebug(const FrameBuffer &shadow_framebuffer); void renderShadowsDebug(const FrameBuffer &shadow_framebuffer,
const PostProcessing *post_processing);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void resetShadowCamNodes() void resetShadowCamNodes()

View File

@ -451,7 +451,7 @@ void PlayerController::handleZipper(bool play_sound)
} }
// Apply the motion blur according to the speed of the kart // Apply the motion blur according to the speed of the kart
irr_driver->getPostProcessing()->giveBoost(m_camera->getIndex()); irr_driver->giveBoost(m_camera->getIndex());
m_kart->showZipperFire(); m_kart->showZipperFire();