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 onUnloadWorld() = 0;
virtual void reset() {}
virtual void giveBoost(unsigned int cam_index) {}
virtual void addSkyBox(const std::vector<irr::video::ITexture*> &texture,
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,
const FrameBuffer& shadow_framebuffer) const
const FrameBuffer& shadow_framebuffer,
const PostProcessing* post_processing) const
{
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++)
{
irr_driver->getPostProcessing()->renderGaussian6BlurLayer(
post_processing->renderGaussian6BlurLayer(
shadow_framebuffer, i,
2.f * shadow_scales[0].first / shadow_scales[i].first,
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& quarter_framebuffer,
const FrameBuffer& color_framebuffer,
GLuint quarter_render_target) const
GLuint quarter_render_target,
const PostProcessing* post_processing) const
{
// To half
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);
glEnable(GL_STENCIL_TEST);
color_framebuffer.bind();
irr_driver->getPostProcessing()->renderGlow(quarter_render_target);//TODO
post_processing->renderGlow(quarter_render_target);//TODO
glDisable(GL_STENCIL_TEST);
}
@ -262,7 +264,7 @@ void renderTransparenPass(const std::vector<RenderGeometry::TexUnit> &TexUnits,
} // 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);
@ -390,9 +392,9 @@ void AbstractGeometryPasses::renderTransparent(const DrawCalls& draw_calls, unsi
irr_driver->getFBO(FBO_COLORS).bind();
glStencilFunc(GL_EQUAL, 1, 0xFF);
irr_driver->getPostProcessing()->renderPassThrough(render_target,
irr_driver->getFBO(FBO_COLORS).getWidth(),
irr_driver->getFBO(FBO_COLORS).getHeight());
post_processing->renderPassThrough(render_target,
irr_driver->getFBO(FBO_COLORS).getWidth(),
irr_driver->getFBO(FBO_COLORS).getHeight());
glDisable(GL_STENCIL_TEST);
} // renderTransparent

View File

@ -40,14 +40,16 @@ protected:
void prepareShadowRendering(const FrameBuffer& shadow_framebuffer) const;
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
void glowPostProcessing(const FrameBuffer& glow_framebuffer,
const FrameBuffer& half_framebuffer,
const FrameBuffer& quater_framebuffer,
const FrameBuffer& color_framebuffer,
GLuint quarter_render_target) const;
GLuint quarter_render_target,
const PostProcessing* post_processing) const;
public:
AbstractGeometryPasses();
@ -67,14 +69,17 @@ public:
const FrameBuffer& half_framebuffer,
const FrameBuffer& quarter_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,
unsigned render_target);
unsigned render_target,
const PostProcessing* post_processing);
virtual void renderShadows(const DrawCalls& draw_calls,
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,
@ -123,7 +128,8 @@ public:
const FrameBuffer& half_framebuffer,
const FrameBuffer& quarter_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);
glow_framebuffer.bind();
@ -147,14 +153,16 @@ public:
glowPostProcessing(glow_framebuffer, half_framebuffer,
quarter_framebuffer, color_framebuffer,
quarter_render_target);
quarter_render_target,
post_processing);
}
void renderShadows(const DrawCalls& draw_calls,
const ShadowMatrices& shadow_matrices,
const FrameBuffer& shadow_framebuffer) const
const FrameBuffer& shadow_framebuffer,
const PostProcessing* post_processing) const
{
prepareShadowRendering(shadow_framebuffer);
@ -167,7 +175,7 @@ public:
glDisable(GL_POLYGON_OFFSET_FILL);
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/particle_kind_manager.hpp"
#include "graphics/per_camera_node.hpp"
#include "graphics/post_processing.hpp"
#include "graphics/referee.hpp"
#include "graphics/render_target.hpp"
#include "graphics/shader_based_renderer.hpp"
@ -138,19 +137,6 @@ 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);
m_device->drop();
@ -170,7 +156,7 @@ IrrDriver::~IrrDriver()
*/
void IrrDriver::reset()
{
if (CVS->isGLSL()) m_post_processing->reset();
m_renderer->reset();
} // reset
void IrrDriver::setPhase(STKRenderingPass p)
@ -642,9 +628,6 @@ void IrrDriver::initDevice()
material2D.AntiAliasing=video::EAAM_FULL_BASIC;
//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,
// so let's decide ourselves...)
m_device->getCursorControl()->setVisible(true);
@ -2427,7 +2410,6 @@ void IrrDriver::clearLights()
} // clearLights
// ----------------------------------------------------------------------------
GLuint IrrDriver::getRenderTargetTexture(TypeRTT which)
{
return m_renderer->getRTT()->getRenderTarget(which);

View File

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

View File

@ -228,6 +228,80 @@ public:
} // 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,
3, float, float, float,
@ -305,6 +379,42 @@ public:
} // render
}; // 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,
GLuint normal_depth_rander_target,
@ -331,6 +441,57 @@ static void renderPointLights(unsigned count,
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
} // 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,
float dt)
@ -416,7 +577,9 @@ void LightingPasses::updateLightsInfo(scene::ICameraSceneNode * const camnode,
void LightingPasses::renderGlobalIllumination( const ShadowMatrices& shadow_matrices,
const FrameBuffer& radiance_hint_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
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));
diffuse_framebuffer.bind();
irr_driver->getPostProcessing()->renderGI( shadow_matrices.getRHMatrix(),
shadow_matrices.getRHExtend(),
radiance_hint_framebuffer);
GlobalIlluminationReconstructionShader::getInstance()
->render(shadow_matrices.getRHMatrix(),
shadow_matrices.getRHExtend(),
radiance_hint_framebuffer,
normal_depth_texture,
depth_stencil_texture);
}
}
// ----------------------------------------------------------------------------
void LightingPasses::renderLights( bool has_shadow,
GLuint normal_depth_rander_target,
GLuint normal_depth_texture,
GLuint depth_stencil_texture,
const FrameBuffer& shadow_framebuffer,
const FrameBuffer& diffuse_specular_framebuffer,
GLuint specular_probe)
{
PostProcessing *post_processing = irr_driver->getPostProcessing();
{
diffuse_specular_framebuffer.bind();
glClear(GL_COLOR_BUFFER_BIT);
{
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
@ -500,27 +666,29 @@ void LightingPasses::renderLights( bool has_shadow,
if (CVS->isESMEnabled())
{
ShadowedSunLightShaderESM::getInstance()->render(normal_depth_rander_target,
ShadowedSunLightShaderESM::getInstance()->render(normal_depth_texture,
depth_stencil_texture,
shadow_framebuffer);
}
else
{
ShadowedSunLightShaderPCF::getInstance()->render(normal_depth_rander_target,
ShadowedSunLightShaderPCF::getInstance()->render(normal_depth_texture,
depth_stencil_texture,
shadow_framebuffer);
}
}
else
post_processing->renderSunlight(irr_driver->getSunDirection(),
irr_driver->getSunColor());
renderSunlight(irr_driver->getSunDirection(),
irr_driver->getSunColor(),
normal_depth_texture,
depth_stencil_texture);
}
//points lights
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_POINTLIGHTS));
renderPointLights(std::min(m_point_light_count, LightBaseClass::MAXLIGHT),
normal_depth_rander_target,
normal_depth_texture,
depth_stencil_texture);
}
} // renderLights
@ -548,10 +716,11 @@ void LightingPasses::renderAmbientScatter(GLuint depth_stencil_texture)
} // 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& colors_framebuffer,
GLuint half1_render_target)
const PostProcessing* post_processing)
{
half1_framebuffer.bind();
glClearColor(0., 0., 0., 0.);
@ -579,23 +748,23 @@ void LightingPasses::renderLightsScatter(const FrameBuffer& half1_framebuffer,
glBindVertexArray(PointLightScatterShader::getInstance()->vao);
PointLightScatterShader::getInstance()
->setTextureUnits(irr_driver->getDepthStencilTexture());
->setTextureUnits(depth_stencil_texture);
PointLightScatterShader::getInstance()
->setUniforms(1.f / (40.f * start), col2);
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);
PostProcessing *post_processing = irr_driver->getPostProcessing();
post_processing->renderGaussian6Blur(half1_framebuffer,
half2_framebuffer, 5., 5.);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
irr_driver->getFBO(FBO_COLORS).bind();
post_processing->renderPassThrough(half1_render_target,
colors_framebuffer.bind();
post_processing->renderPassThrough(half1_framebuffer.getRTT()[0],
colors_framebuffer.getWidth(),
colors_framebuffer.getHeight());
} // renderLightsScatter

View File

@ -21,11 +21,22 @@
#include "graphics/glwrap.hpp"
#include <irrlicht.h>
class PostProcessing;
class LightingPasses
{
private:
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:
LightingPasses(): m_point_light_count(0){}
@ -36,18 +47,21 @@ public:
void renderGlobalIllumination( const ShadowMatrices& shadow_matrices,
const FrameBuffer& radiance_hint_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,
GLuint normal_depth_rander_target,
GLuint normal_depth_texture,
GLuint depth_stencil_texture,
const FrameBuffer& shadow_framebuffer,
const FrameBuffer& diffuse_specular_framebuffer,
GLuint specular_probe);
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& colors_framebuffer,
GLuint half1_render_target);
const PostProcessing* post_processing);

View File

@ -21,7 +21,6 @@
#include "graphics/callbacks.hpp"
#include "graphics/camera.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/mlaa_areamap.hpp"
#include "graphics/render_target.hpp"
@ -217,10 +216,11 @@ public:
1, "depth", ST_BILINEAR_CLAMPED_FILTERED);
} // 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],
irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0] );
linear_depth.getRTT()[0] );
drawFullScreenEffect(core::vector2df(1.0f/width, 1.0f/height));
} // render
@ -243,12 +243,13 @@ public:
} // ComputeGaussian17TapHShader
// ------------------------------------------------------------------------
void render(const FrameBuffer &fb, const FrameBuffer &auxiliary,
const FrameBuffer &linear_depth,
int width, int height)
{
use();
glBindSampler(m_dest_tu, 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,
0, GL_WRITE_ONLY, GL_R16F);
setUniforms(core::vector2df(1.0f/width, 1.0f/height));
@ -272,10 +273,11 @@ public:
1, "depth", ST_BILINEAR_CLAMPED_FILTERED);
} // 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],
irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]);
linear_depth.getRTT()[0]);
drawFullScreenEffect(core::vector2df(1.0f/width, 1.0f/height));
} // render
@ -298,13 +300,14 @@ public:
assignTextureUnit(m_dest_tu, "dest");
} // 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)
{
use();
glBindSampler(m_dest_tu, 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,
GL_WRITE_ONLY, GL_R16F);
setUniforms(core::vector2df(1.0f/width, 1.0f/height));
@ -354,11 +357,13 @@ public:
3, "tex_dust", ST_BILINEAR_FILTERED);
} // 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),
irr_driver->getRenderTargetTexture(RTT_BLOOM_256),
irr_driver->getRenderTargetTexture(RTT_BLOOM_512),
setTextureUnits(render_target_bloom_128,
render_target_bloom_256,
render_target_bloom_512,
getTextureGLuint(lensDustTex));
drawFullScreenEffect();
} // render
@ -379,11 +384,13 @@ public:
2, "tex_512", ST_BILINEAR_FILTERED);
} // 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),
irr_driver->getRenderTargetTexture(RTT_LENS_256),
irr_driver->getRenderTargetTexture(RTT_LENS_512));
setTextureUnits(render_target_lens_128,
render_target_lens_256,
render_target_lens_512);
drawFullScreenEffect();
} // render
@ -426,51 +433,15 @@ public:
1, "dtex", ST_NEAREST_FILTERED);
} // DepthOfFieldShader
// ------------------------------------------------------------------------
void render(const FrameBuffer &fb, GLuint rtt)
void render(const FrameBuffer &framebuffer, GLuint color_texture, GLuint depth_stencil_texture)
{
fb.bind();
setTextureUnits(rtt, irr_driver->getDepthStencilTexture());
framebuffer.bind();
setTextureUnits(color_texture, depth_stencil_texture);
drawFullScreenEffect();
} // render
}; // 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>
{
@ -490,41 +461,6 @@ public:
} // 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>
{
@ -587,9 +523,9 @@ public:
assignSamplerNames(0, "texture", ST_BILINEAR_FILTERED);
} // LinearizeDepthShader
// ------------------------------------------------------------------------
void render()
void render(GLuint depth_stencil_texture)
{
setTextureUnits(irr_driver->getDepthStencilTexture());
setTextureUnits(depth_stencil_texture);
scene::ICameraSceneNode *c = irr_driver->getSceneManager()->getActiveCamera();
drawFullScreenEffect(c->getNearValue(), c->getFarValue() );
@ -637,9 +573,9 @@ public:
assignSamplerNames(0, "dtex", ST_SEMI_TRILINEAR);
} // 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);
drawFullScreenEffect(irr_driver->getSSAORadius(),
@ -666,9 +602,9 @@ public:
1, "dtex", ST_NEAREST_FILTERED);
} // 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();
// Todo : use a previousPVMatrix per cam, not global
drawFullScreenEffect(cam->getPreviousPVMatrix(),
@ -753,10 +689,12 @@ public:
1, "areaMap", ST_NEAREST_FILTERED);
} // 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();
setTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_TMP),
setTextureUnits(rtt_mlaa_tmp,
getTextureGLuint(area_map));
drawFullScreenEffect(pixel_size);
@ -777,49 +715,18 @@ public:
1, "colorMap", ST_NEAREST_FILTERED);
} // MLAAGatherSHader
// ------------------------------------------------------------------------
void render(const core::vector2df &pixel_size)
void render(const core::vector2df &pixel_size,
GLuint rtt_mlaa_blend,
GLuint rtt_mlaa_tmp)
{
use();
setTextureUnits(irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND),
irr_driver->getRenderTargetTexture(RTT_MLAA_TMP));
setTextureUnits(rtt_mlaa_blend,
rtt_mlaa_tmp);
drawFullScreenEffect(pixel_size);
} // render
}; // 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,
core::vector3df>
@ -1008,48 +915,11 @@ void PostProcessing::update(float dt)
} // update
// ----------------------------------------------------------------------------
static void renderBloom(GLuint in)
void PostProcessing::renderBloom(GLuint in)
{
BloomShader::getInstance()->render(in);
} // 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,
const core::matrix4 &rh_matrix,
@ -1068,23 +938,6 @@ void PostProcessing::renderRHDebug(unsigned SHR, unsigned SHG, unsigned SHB,
glDisable(GL_PROGRAM_POINT_SIZE);
} // 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)
{
@ -1109,7 +962,7 @@ static std::vector<float> getGaussianWeight(float sigma, size_t count)
// ----------------------------------------------------------------------------
void PostProcessing::renderGaussian3Blur(const FrameBuffer &in_fbo,
const FrameBuffer &auxiliary)
const FrameBuffer &auxiliary) const
{
assert(in_fbo.getWidth() == auxiliary.getWidth() &&
in_fbo.getHeight() == auxiliary.getHeight());
@ -1130,7 +983,7 @@ void PostProcessing::renderGaussian3Blur(const FrameBuffer &in_fbo,
// ----------------------------------------------------------------------------
void PostProcessing::renderGaussian6BlurLayer(const FrameBuffer &in_fbo,
size_t layer, float sigma_h,
float sigma_v)
float sigma_v) const
{
GLuint layer_tex;
glGenTextures(1, &layer_tex);
@ -1190,7 +1043,7 @@ void PostProcessing::renderGaussian6BlurLayer(const FrameBuffer &in_fbo,
// ----------------------------------------------------------------------------
void PostProcessing::renderGaussian6Blur(const FrameBuffer &in_fbo,
const FrameBuffer &auxiliary, float sigma_v,
float sigma_h)
float sigma_h) const
{
assert(in_fbo.getWidth() == auxiliary.getWidth() &&
in_fbo.getHeight() == auxiliary.getHeight());
@ -1246,7 +1099,7 @@ void PostProcessing::renderGaussian6Blur(const FrameBuffer &in_fbo,
// ----------------------------------------------------------------------------
void PostProcessing::renderHorizontalBlur(const FrameBuffer &in_fbo,
const FrameBuffer &auxiliary)
const FrameBuffer &auxiliary) const
{
assert(in_fbo.getWidth() == auxiliary.getWidth() &&
in_fbo.getHeight() == auxiliary.getHeight());
@ -1262,7 +1115,8 @@ void PostProcessing::renderHorizontalBlur(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() &&
in_fbo.getHeight() == auxiliary.getHeight());
@ -1273,6 +1127,7 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
{
auxiliary.bind();
Gaussian17TapHShader::getInstance()->render(in_fbo,
linear_depth,
in_fbo.getWidth(),
in_fbo.getHeight());
}
@ -1280,6 +1135,7 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
{
ComputeGaussian17TapHShader::getInstance()->render(in_fbo,
auxiliary,
linear_depth,
in_fbo.getWidth(),
in_fbo.getHeight());
}
@ -1291,6 +1147,7 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
{
in_fbo.bind();
Gaussian17TapVShader::getInstance()->render(auxiliary,
linear_depth,
in_fbo.getWidth(),
in_fbo.getHeight());
}
@ -1298,6 +1155,7 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
{
ComputeGaussian17TapVShader::getInstance()->render(auxiliary,
in_fbo,
linear_depth,
in_fbo.getWidth(),
in_fbo.getHeight());
}
@ -1308,13 +1166,13 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo,
// ----------------------------------------------------------------------------
void PostProcessing::renderPassThrough(GLuint tex, unsigned width,
unsigned height)
unsigned height) const
{
PassThroughShader::getInstance()->render(tex, width, height);
} // renderPassThrough
// ----------------------------------------------------------------------------
void PostProcessing::renderTextureLayer(unsigned tex, unsigned layer)
void PostProcessing::renderTextureLayer(unsigned tex, unsigned layer) const
{
LayerPassThroughShader::getInstance()->use();
LayerPassThroughShader::getInstance()->bindVertexArray();
@ -1328,27 +1186,30 @@ void PostProcessing::renderTextureLayer(unsigned tex, unsigned layer)
} // renderTextureLayer
// ----------------------------------------------------------------------------
void PostProcessing::renderGlow(unsigned tex)
void PostProcessing::renderGlow(unsigned tex) const
{
GlowShader::getInstance()->render(tex);
} // 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_BLEND);
// Generate linear depth buffer
irr_driver->getFBO(FBO_LINEAR_DEPTH).bind();
LinearizeDepthShader::getInstance()->render();
irr_driver->getFBO(FBO_SSAO).bind();
SSAOShader::getInstance()->render();
linear_depth_framebuffer.bind();
LinearizeDepthShader::getInstance()->render(depth_stencil_texture);
ssao_framebuffer.bind();
SSAOShader::getInstance()->render(linear_depth_framebuffer.getRTT()[0]);
} // renderSSAO
// ----------------------------------------------------------------------------
void PostProcessing::renderMotionBlur(unsigned , const FrameBuffer &in_fbo,
FrameBuffer &out_fbo)
FrameBuffer &out_fbo,
GLuint depth_stencil_texture)
{
MotionBlurProvider * const cb =
(MotionBlurProvider *)Shaders::getCallback(ES_MOTIONBLUR);
@ -1376,16 +1237,88 @@ void PostProcessing::renderMotionBlur(unsigned , const FrameBuffer &in_fbo,
glClear(GL_COLOR_BUFFER_BIT);
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
// ----------------------------------------------------------------------------
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
// ----------------------------------------------------------------------------
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,
const FrameBuffer& mlaa_blend_framebuffer,
@ -1412,7 +1345,7 @@ void PostProcessing::applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer,
mlaa_blend_framebuffer.bind();
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
FrameBuffer::Blit(mlaa_colors_framebuffer,
@ -1420,7 +1353,8 @@ void PostProcessing::applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer,
// Pass 3: gather
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.
glDisable(GL_STENCIL_TEST);
@ -1442,10 +1376,11 @@ void PostProcessing::renderLightning(core::vector3df intensity)
/** Render the post-processed scene */
FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
bool isRace,
RTT *rtts,
GL3RenderTarget *specified_render_target)
{
FrameBuffer *in_fbo = &irr_driver->getFBO(FBO_COLORS);
FrameBuffer *out_fbo = &irr_driver->getFBO(FBO_TMP1_WITH_DS);
FrameBuffer *in_fbo = &rtts->getFBO(FBO_COLORS);
FrameBuffer *out_fbo = &rtts->getFBO(FBO_TMP1_WITH_DS);
// Each effect uses these as named, and sets them up for the next effect.
// This allows chaining effects where some may be disabled.
@ -1457,97 +1392,28 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
World *world = World::getWorld();
Physics *physics = world ? world->getPhysics() : NULL;
if (isRace && UserConfigParams::m_dof && (physics == NULL || !physics->isDebug()))
{
PROFILER_PUSH_CPU_MARKER("- DoF", 0xFF, 0x00, 0x00);
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);
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);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GODRAYS));
bool hasgodrays = false;
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);
}
renderGodRays(camnode, *out_fbo, rtts->getFBO(FBO_QUARTER1), rtts->getFBO(FBO_QUARTER2));
PROFILER_POP_CPU_MARKER();
}
// Simulate camera defects from there
{
PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_BLOOM));
@ -1557,46 +1423,48 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
glClear(GL_STENCIL_BUFFER_BIT);
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);
irr_driver->getFBO(FBO_BLOOM_512).bind();
renderBloom(irr_driver->getRenderTargetTexture(RTT_BLOOM_1024));
rtts->getFBO(FBO_BLOOM_512).bind();
renderBloom(rtts->getRenderTarget(RTT_BLOOM_1024));
// Downsample
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512),
irr_driver->getFBO(FBO_BLOOM_256),
FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_512),
rtts->getFBO(FBO_BLOOM_256),
GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256),
irr_driver->getFBO(FBO_BLOOM_128),
FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_256),
rtts->getFBO(FBO_BLOOM_128),
GL_COLOR_BUFFER_BIT, GL_LINEAR);
// Copy for lens flare
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512),
irr_driver->getFBO(FBO_LENS_512),
FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_512),
rtts->getFBO(FBO_LENS_512),
GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256),
irr_driver->getFBO(FBO_LENS_256),
FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_256),
rtts->getFBO(FBO_LENS_256),
GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_128),
irr_driver->getFBO(FBO_LENS_128),
FrameBuffer::Blit(rtts->getFBO(FBO_BLOOM_128),
rtts->getFBO(FBO_LENS_128),
GL_COLOR_BUFFER_BIT, GL_LINEAR);
// Blur
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_512),
irr_driver->getFBO(FBO_TMP_512), 1., 1.);
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_256),
irr_driver->getFBO(FBO_TMP_256), 1., 1.);
renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_128),
irr_driver->getFBO(FBO_TMP_128), 1., 1.);
renderGaussian6Blur(rtts->getFBO(FBO_BLOOM_512),
rtts->getFBO(FBO_TMP_512), 1., 1.);
renderGaussian6Blur(rtts->getFBO(FBO_BLOOM_256),
rtts->getFBO(FBO_TMP_256), 1., 1.);
renderGaussian6Blur(rtts->getFBO(FBO_BLOOM_128),
rtts->getFBO(FBO_TMP_128), 1., 1.);
renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_512),
irr_driver->getFBO(FBO_TMP_512));
renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_256),
irr_driver->getFBO(FBO_TMP_256));
renderHorizontalBlur(irr_driver->getFBO(FBO_LENS_128),
irr_driver->getFBO(FBO_TMP_128));
renderHorizontalBlur(rtts->getFBO(FBO_LENS_512),
rtts->getFBO(FBO_TMP_512));
renderHorizontalBlur(rtts->getFBO(FBO_LENS_256),
rtts->getFBO(FBO_TMP_256));
renderHorizontalBlur(rtts->getFBO(FBO_LENS_128),
rtts->getFBO(FBO_TMP_128));
// Additively blend on top of tmp1
@ -1605,8 +1473,14 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
BloomBlendShader::getInstance()->render();
LensBlendShader::getInstance()->render();
BloomBlendShader::getInstance()
->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);
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() &&
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);
}
PROFILER_POP_CPU_MARKER();
@ -1668,16 +1542,16 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
out_fbo->bind();
renderPassThrough(in_fbo->getRTT()[0],
out_fbo->getWidth(),
out_fbo->getHeight());
out_fbo->getWidth(),
out_fbo->getHeight());
if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
{
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MLAA));
applyMLAA(irr_driver->getFBO(FBO_MLAA_TMP),
irr_driver->getFBO(FBO_MLAA_BLEND),
applyMLAA(rtts->getFBO(FBO_MLAA_TMP),
rtts->getFBO(FBO_MLAA_BLEND),
*out_fbo);
PROFILER_POP_CPU_MARKER();
}

View File

@ -22,8 +22,8 @@
#include "S3DVertex.h"
#include "SMaterial.h"
#include "graphics/camera.hpp"
#include "graphics/glwrap.hpp"
class FrameBuffer;
class GL3RenderTarget;
#include <vector>
@ -75,47 +75,52 @@ public:
void begin();
void update(float dt);
/** Generate diffuse and specular map */
void renderSunlight(const core::vector3df &direction,
const video::SColorf &col);
void renderSSAO();
void renderEnvMap(unsigned skycubemap);
void renderBloom(GLuint in);
void renderSSAO(const FrameBuffer& linear_depth_framebuffer,
const FrameBuffer& ssao_framebuffer,
GLuint depth_stencil_texture);
void renderRHDebug(unsigned SHR, unsigned SHG, unsigned SHB,
const core::matrix4 &rh_matrix,
const core::vector3df &rh_extend);
void renderGI(const core::matrix4 &rh_matrix,
const core::vector3df &rh_extend,
const FrameBuffer &fb);
/** 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,
float sigmaV, float sigmaH);
void renderHorizontalBlur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary);
float sigmaV, float sigmaH) const;
void renderHorizontalBlur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary) const;
void renderGaussian6BlurLayer(const FrameBuffer &in_fbo, size_t layer,
float sigmaH, float sigmaV);
void renderGaussian17TapBlur(const FrameBuffer &in_fbo, const FrameBuffer &auxiliary);
float sigmaH, float sigmaV) const;
void renderGaussian17TapBlur(const FrameBuffer &in_fbo,
const FrameBuffer &auxiliary,
const FrameBuffer &linear_depth) const;
/** Render tex. Used for blit/texture resize */
void renderPassThrough(unsigned tex, unsigned width, unsigned height);
void renderTextureLayer(unsigned tex, unsigned layer);
void renderPassThrough(unsigned tex, unsigned width, unsigned height) const;
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,
const FrameBuffer& mlaa_blend_framebuffer,
const FrameBuffer& mlaa_colors_framebuffer);
void renderMotionBlur(unsigned cam, const FrameBuffer &in_fbo,
FrameBuffer &out_fbo);
void renderGlow(unsigned tex);
FrameBuffer &out_fbo,
GLuint depth_stencil_texture);
void renderGlow(unsigned tex) const;
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 */
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
#endif // HEADER_POST_PROCESSING_HPP

View File

@ -211,13 +211,16 @@ void ShaderBasedRenderer::renderSSAO() const
m_rtts->getFBO(FBO_SSAO).bind();
glClearColor(1., 1., 1., 1.);
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.
FrameBuffer::Blit(m_rtts->getFBO(FBO_SSAO),
m_rtts->getFBO(FBO_HALF1_R),
GL_COLOR_BUFFER_BIT, GL_LINEAR);
irr_driver->getPostProcessing()->renderGaussian17TapBlur(m_rtts->getFBO(FBO_HALF1_R),
m_rtts->getFBO(FBO_HALF2_R));
m_post_processing->renderGaussian17TapBlur(m_rtts->getFBO(FBO_HALF1_R),
m_rtts->getFBO(FBO_HALF2_R),
m_rtts->getFBO(FBO_LINEAR_DEPTH));
} // renderSSAO
@ -227,7 +230,6 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
bool hasShadow,
bool forceRTT)
{
PostProcessing *post_processing = irr_driver->getPostProcessing();
m_wind_dir = getWindDir(); //TODO
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);
m_geometry_passes->renderShadows(m_draw_calls,
m_shadow_matrices,
m_rtts->getShadowFrameBuffer());
m_rtts->getShadowFrameBuffer(),
m_post_processing);
PROFILER_POP_CPU_MARKER();
if (CVS->isGlobalIlluminationEnabled())
{
@ -312,7 +315,9 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
m_lighting_passes.renderGlobalIllumination( m_shadow_matrices,
m_rtts->getRadianceHintFrameBuffer(),
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;
@ -398,10 +403,11 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
{
PROFILER_PUSH_CPU_MARKER("- PointLight Scatter", 0xFF, 0x00, 0x00);
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_COLORS),
m_rtts->getRenderTarget(RTT_HALF1));
m_post_processing);
PROFILER_POP_CPU_MARKER();
}
@ -409,20 +415,23 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
{
glDisable(GL_BLEND);
m_rtts->getFBO(FBO_COLORS).bind();
post_processing->renderRHDebug(m_rtts->getRadianceHintFrameBuffer().getRTT()[0],
m_rtts->getRadianceHintFrameBuffer().getRTT()[1],
m_rtts->getRadianceHintFrameBuffer().getRTT()[2],
m_shadow_matrices.getRHMatrix(),
m_shadow_matrices.getRHExtend());
m_post_processing->renderRHDebug(m_rtts->getRadianceHintFrameBuffer().getRTT()[0],
m_rtts->getRadianceHintFrameBuffer().getRTT()[1],
m_rtts->getRadianceHintFrameBuffer().getRTT()[2],
m_shadow_matrices.getRHMatrix(),
m_shadow_matrices.getRHExtend());
}
if (irr_driver->getGI())
{
glDisable(GL_BLEND);
m_rtts->getFBO(FBO_COLORS).bind();
post_processing->renderGI(m_shadow_matrices.getRHMatrix(),
m_shadow_matrices.getRHExtend(),
m_rtts->getRadianceHintFrameBuffer());
m_lighting_passes.renderGlobalIllumination(m_shadow_matrices,
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);
@ -436,7 +445,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
m_rtts->getFBO(FBO_HALF1),
m_rtts->getFBO(FBO_QUARTER1),
m_rtts->getFBO(FBO_COLORS),
m_rtts->getRenderTarget(RTT_QUARTER1));
m_rtts->getRenderTarget(RTT_QUARTER1),
m_post_processing);
} // end glow
PROFILER_POP_CPU_MARKER();
@ -445,7 +455,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TRANSPARENT));
m_geometry_passes->renderTransparent(m_draw_calls,
m_rtts->getRenderTarget(RTT_DISPLACE));
m_rtts->getRenderTarget(RTT_DISPLACE),
m_post_processing);
PROFILER_POP_CPU_MARKER();
}
@ -483,7 +494,6 @@ void ShaderBasedRenderer::renderParticles()
// m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
}
void ShaderBasedRenderer::renderBoundingBoxes()
{
Shaders::ColoredLine *line = Shaders::ColoredLine::getInstance();
@ -547,8 +557,7 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
const core::recti &viewport = camera->getViewport();
bool isRace = StateManager::get()->getGameState() == GUIEngine::GAME;
PostProcessing * post_processing = irr_driver->getPostProcessing();
FrameBuffer *fbo = post_processing->render(camnode, isRace);
FrameBuffer *fbo = m_post_processing->render(camnode, isRace, m_rtts);
if (irr_driver->getNormals())
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);
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())
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
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())
{
m_shadow_matrices.renderShadowsDebug(m_rtts->getShadowFrameBuffer());
m_shadow_matrices.renderShadowsDebug(m_rtts->getShadowFrameBuffer(), m_post_processing);
}
else
{
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
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);
}
}
@ -592,10 +601,26 @@ ShaderBasedRenderer::ShaderBasedRenderer()
m_geometry_passes = new GeometryPasses<IndirectDrawPolicy>();
else
m_geometry_passes = new GeometryPasses<GL3DrawPolicy>();
// Initialize post-processing if supported
m_post_processing = new PostProcessing(irr_driver->getVideoDriver());
}
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_spherical_harmonics;
delete m_skybox;
@ -619,6 +644,16 @@ void ShaderBasedRenderer::onUnloadWorld()
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,
const std::vector<video::ITexture*> &spherical_harmonics_textures)
@ -687,7 +722,7 @@ void ShaderBasedRenderer::render(float dt)
// Start the RTT for post-processing.
// We do this before beginScene() because we want to capture the glClear()
// 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.
Track *track = world->getTrack();
@ -800,7 +835,7 @@ void ShaderBasedRenderer::render(float dt)
irr_driver->getVideoDriver()->endScene();
PROFILER_POP_CPU_MARKER();
irr_driver->getPostProcessing()->update(dt);
m_post_processing->update(dt);
removeItemsInGlowingList();
}
@ -838,7 +873,7 @@ void ShaderBasedRenderer::renderToTexture(GL3RenderTarget *render_target,
updateLightsInfo(camera, dt);
uploadLightingData();
renderScene(camera, dt, false, true);
irr_driver->getPostProcessing()->render(camera, false, render_target);
m_post_processing->render(camera, false, m_rtts, render_target);
// reset
glViewport(0, 0,

View File

@ -28,8 +28,9 @@
#include <map>
#include <string>
class RenderTarget;
class GL3RenderTarget;
class RenderTarget;
class PostProcessing;
class ShaderBasedRenderer: public AbstractRenderer
{
@ -42,6 +43,8 @@ private:
AbstractGeometryPasses *m_geometry_passes;
LightingPasses m_lighting_passes;
ShadowMatrices m_shadow_matrices;
/** Post-processing. */
PostProcessing *m_post_processing;
/** Static glowing things are loaded once per track.
* Glowing items can appear ordisappear each frame */
@ -92,6 +95,8 @@ public:
void onLoadWorld() ;
void onUnloadWorld();
void reset() override;
void giveBoost(unsigned int cam_index) override;
void addSkyBox(const std::vector<irr::video::ITexture*> &texture,
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);
}
// ----------------------------------------------------------------------------
void ShadowMatrices::renderShadowsDebug(const FrameBuffer &shadow_framebuffer)
void ShadowMatrices::renderShadowsDebug(const FrameBuffer &shadow_framebuffer,
const PostProcessing *post_processing)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 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);
renderWireFrameFrustrum(m_shadows_cam[0], 0);
glViewport(UserConfigParams::m_width / 2, UserConfigParams::m_height / 2,

View File

@ -34,7 +34,7 @@ namespace irr
using namespace irr;
class PostProcessing;
class ShadowMatrices
{
@ -70,7 +70,8 @@ public:
GLuint depth_stencil_texture);
void addLight(const core::vector3df &pos);
void updateSunOrthoMatrices();
void renderShadowsDebug(const FrameBuffer &shadow_framebuffer);
void renderShadowsDebug(const FrameBuffer &shadow_framebuffer,
const PostProcessing *post_processing);
// ------------------------------------------------------------------------
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
irr_driver->getPostProcessing()->giveBoost(m_camera->getIndex());
irr_driver->giveBoost(m_camera->getIndex());
m_kart->showZipperFire();