diff --git a/data/gfx/gfx_mudPot_a.xml b/data/gfx/gfx_mudPot_a.xml
new file mode 100644
index 000000000..cc6ead88f
--- /dev/null
+++ b/data/gfx/gfx_mudPot_a.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/shaders/fog.frag b/data/shaders/fog.frag
index cb5ec7348..104b57d83 100644
--- a/data/shaders/fog.frag
+++ b/data/shaders/fog.frag
@@ -1,10 +1,6 @@
uniform sampler2D tex;
-uniform float fogmax;
-uniform float startH;
-uniform float endH;
-uniform float start;
-uniform float end;
+uniform float density;
uniform vec3 col;
out vec4 FragColor;
@@ -14,14 +10,12 @@ vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
void main()
{
- vec2 uv = gl_FragCoord.xy / screen;
- float z = texture(tex, uv).x;
- vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);
+ vec2 uv = 2. * gl_FragCoord.xy / screen;
+ float z = texture(tex, uv).x;
+ vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);
- float dist = length(xpos.xyz);
- float fog = smoothstep(start, end, dist);
+ float dist = length(xpos.xyz);
+ vec3 fog = col * (1. - exp(- density * dist));
- fog = min(fog, fogmax);
-
- FragColor = vec4(col, fog);
+ FragColor = vec4(fog, 1.);
}
diff --git a/data/shaders/gaussian6h.frag b/data/shaders/gaussian6h.frag
index e90cfd132..f788df9d1 100644
--- a/data/shaders/gaussian6h.frag
+++ b/data/shaders/gaussian6h.frag
@@ -1,7 +1,6 @@
uniform sampler2D tex;
uniform vec2 pixel;
-
-float sigma = 1.;
+uniform float sigma;
// Gaussian separated blur with radius 6.
diff --git a/data/shaders/gaussian6v.frag b/data/shaders/gaussian6v.frag
index cf5ec0ce6..4df5905b0 100644
--- a/data/shaders/gaussian6v.frag
+++ b/data/shaders/gaussian6v.frag
@@ -1,7 +1,6 @@
uniform sampler2D tex;
uniform vec2 pixel;
-
-float sigma = 1.;
+uniform float sigma;
// Gaussian separated blur with radius 6.
diff --git a/data/shaders/pointlightscatter.frag b/data/shaders/pointlightscatter.frag
new file mode 100644
index 000000000..2d6ee6cba
--- /dev/null
+++ b/data/shaders/pointlightscatter.frag
@@ -0,0 +1,46 @@
+uniform sampler2D dtex;
+uniform float density;
+uniform vec3 fogcol;
+
+flat in vec3 center;
+flat in float energy;
+flat in vec3 col;
+flat in float radius;
+
+out vec4 Fog;
+
+vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
+
+void main()
+{
+ vec4 pseudocenter = ViewMatrix * vec4(center.xyz, 1.0);
+ pseudocenter /= pseudocenter.w;
+ vec3 light_pos = pseudocenter.xyz;
+ vec3 light_col = col.xyz;
+
+ // Compute pixel position
+ vec2 texc = 2. * gl_FragCoord.xy / screen;
+ float z = texture(dtex, texc).x;
+ vec4 pixelpos = getPosFromUVDepth(vec3(texc, z), InverseProjectionMatrix);
+ vec3 eyedir = -normalize(pixelpos.xyz);
+
+ vec3 farthestpoint = - eyedir * (min(dot(-eyedir, light_pos) + radius, length(pixelpos.xyz)));
+ vec3 closestpoint = - eyedir * (dot(-eyedir, light_pos) - radius);
+ if (closestpoint.z < 1.) closestpoint = vec3(0.);
+
+ float stepsize = length(farthestpoint - closestpoint) / 16;
+ vec3 fog = vec3(0.);
+ vec3 xpos = farthestpoint;
+
+ for (int i = 0; i < 16; i++)
+ {
+ float d = distance(light_pos, xpos);
+ float l = (16 - i) * stepsize;
+ float att = energy * 20. / (1. + d * d);
+ att *= max((radius - d) / radius, 0.);
+ fog += density * light_col * att * exp(- density * d) * exp(- density * l) * stepsize;
+ xpos += stepsize * eyedir;
+ }
+
+ Fog = vec4(fogcol * fog, 1.);
+}
diff --git a/data/shaders/volumetriclight.frag b/data/shaders/volumetriclight.frag
new file mode 100644
index 000000000..0b4952068
--- /dev/null
+++ b/data/shaders/volumetriclight.frag
@@ -0,0 +1,43 @@
+#ifdef GL_ARB_bindless_texture
+layout(bindless_sampler) uniform sampler2D tex;
+#else
+uniform sampler2D tex;
+#endif
+
+
+uniform float fogmax;
+uniform float startH;
+uniform float endH;
+uniform float start;
+uniform float end;
+uniform vec3 col;
+
+in vec2 uv;
+in vec4 color;
+out vec4 FragColor;
+
+
+void main()
+{
+ vec4 diffusecolor = texture(tex, uv);
+#ifdef GL_ARB_bindless_texture
+ diffusecolor.xyz = pow(diffusecolor.xyz, vec3(2.2));
+#endif
+ diffusecolor.xyz *= pow(color.xyz, vec3(2.2));
+ diffusecolor.a *= color.a;
+ vec3 tmp = vec3(gl_FragCoord.xy / screen, gl_FragCoord.z);
+ tmp = 2. * tmp - 1.;
+
+ vec4 xpos = vec4(tmp, 1.0);
+ xpos = InverseProjectionMatrix * xpos;
+ xpos.xyz /= xpos.w;
+
+ float dist = length(xpos.xyz);
+ float fog = smoothstep(start, end, dist);
+
+ fog = min(fog, fogmax);
+
+ vec4 finalcolor = vec4(col, 0.) * fog + diffusecolor *(1. - fog);
+ FragColor = vec4(finalcolor.rgb * finalcolor.a, finalcolor.a);
+ //FragColor = vec4(1.0, 0.0, 0.0, finalcolor.a);
+}
diff --git a/lib/bullet/src/BulletDynamics/Dynamics/btRigidBody.h b/lib/bullet/src/BulletDynamics/Dynamics/btRigidBody.h
index 1036c576c..caea847f8 100644
--- a/lib/bullet/src/BulletDynamics/Dynamics/btRigidBody.h
+++ b/lib/bullet/src/BulletDynamics/Dynamics/btRigidBody.h
@@ -632,6 +632,10 @@ public:
{
if (m_inverseMass)
{
+ btAssert(!isnan(impulseMagnitude));
+ btAssert(!isnan(linearComponent.getX()));
+ btAssert(!isnan(linearComponent.getY()));
+ btAssert(!isnan(linearComponent.getZ()));
m_deltaLinearVelocity += linearComponent*impulseMagnitude;
m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
}
diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp
index 60cd0c1fd..9bffa86cc 100644
--- a/src/graphics/irr_driver.hpp
+++ b/src/graphics/irr_driver.hpp
@@ -416,6 +416,7 @@ private:
void renderGlow(std::vector& glows);
void renderSSAO();
void renderLights(unsigned pointlightCount, bool hasShadow);
+ void renderLightsScatter(unsigned pointlightCount);
void renderShadowsDebug();
void doScreenShot();
void PrepareDrawCalls(scene::ICameraSceneNode *camnode);
diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp
index 1b2503be5..0190fce43 100644
--- a/src/graphics/post_processing.cpp
+++ b/src/graphics/post_processing.cpp
@@ -327,15 +327,15 @@ void PostProcessing::renderGaussian6BlurLayer(FrameBuffer &in_fbo)
glGenTextures(1, &LayerTex);
glTextureView(LayerTex, GL_TEXTURE_2D, in_fbo.getRTT()[0], GL_R32F, 0, 1, i, 1);
FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(LayerTex);
- DrawFullScreenEffect(core::vector2df(1. / 1024., 1. / 1024.));
+ DrawFullScreenEffect(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f);
in_fbo.BindLayer(i);
FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(irr_driver->getFBO(FBO_BLOOM_1024).getRTT()[0]);
- DrawFullScreenEffect(core::vector2df(1. / 1024., 1. / 1024.));
+ DrawFullScreenEffect(core::vector2df(1.f / 1024.f, 1.f / 1024.f), 1.f);
glDeleteTextures(1, &LayerTex);
}
}
-void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary)
+void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary, float sigmaV, float sigmaH)
{
assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight());
float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight();
@@ -343,57 +343,16 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
auxiliary.Bind();
FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
- DrawFullScreenEffect(core::vector2df(inv_width, inv_height));
+ DrawFullScreenEffect(core::vector2df(inv_width, inv_height), sigmaV);
}
{
in_fbo.Bind();
FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
- DrawFullScreenEffect(core::vector2df(inv_width, inv_height));
+ DrawFullScreenEffect(core::vector2df(inv_width, inv_height), sigmaH);
}
}
-void PostProcessing::renderHorizontalBlur(FrameBuffer &in_fbo, FrameBuffer &auxiliary)
-{
- assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight());
- float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight();
- {
- auxiliary.Bind();
-
- FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
- DrawFullScreenEffect(core::vector2df(inv_width, inv_height));
- }
- {
- in_fbo.Bind();
-
- FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
- DrawFullScreenEffect(core::vector2df(inv_width, inv_height));
- }
- {
- auxiliary.Bind();
-
- FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
- DrawFullScreenEffect(core::vector2df(inv_width, inv_height));
- }
- {
- in_fbo.Bind();
-
- FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
- DrawFullScreenEffect(core::vector2df(inv_width, inv_height));
- }
- {
- auxiliary.Bind();
-
- FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
- DrawFullScreenEffect(core::vector2df(inv_width, inv_height));
- }
- {
- in_fbo.Bind();
-
- FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
- DrawFullScreenEffect(core::vector2df(inv_width, inv_height));
- }
-}
void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &auxiliary)
{
@@ -515,11 +474,11 @@ void PostProcessing::renderFog()
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFunc(GL_ONE, GL_ONE);
FullScreenShader::FogShader::getInstance()->SetTextureUnits(irr_driver->getDepthStencilTexture());
- DrawFullScreenEffect(fogmax, startH, endH, start, end, col);
+ DrawFullScreenEffect(1. / (40. * start), col);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
@@ -763,13 +722,14 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
// Blur
- renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_TMP_512));
- renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_TMP_256));
- renderGaussian6Blur(irr_driver->getFBO(FBO_BLOOM_128), irr_driver->getFBO(FBO_TMP_128));
+
+ 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.);
- 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));
+ renderGaussian6Blur(irr_driver->getFBO(FBO_LENS_512), irr_driver->getFBO(FBO_TMP_512), 0.01, 10.);
+ renderGaussian6Blur(irr_driver->getFBO(FBO_LENS_256), irr_driver->getFBO(FBO_TMP_256), 0.01, 10.);
+ renderGaussian6Blur(irr_driver->getFBO(FBO_LENS_128), irr_driver->getFBO(FBO_TMP_128), 0.01, 10.);
// Additively blend on top of tmp1
in_fbo->Bind();
diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp
index cced5ec2a..702b7981c 100644
--- a/src/graphics/post_processing.hpp
+++ b/src/graphics/post_processing.hpp
@@ -87,8 +87,9 @@ public:
/** Blur the in texture */
void renderGaussian3Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
- void renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
- void renderHorizontalBlur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
+
+ void renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxiliary, float sigmaV, float sigmaH);
+
void renderGaussian6BlurLayer(FrameBuffer &in_fbo);
void renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &auxiliary);
diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp
index 654f8d6f5..10d9e9530 100644
--- a/src/graphics/render.cpp
+++ b/src/graphics/render.cpp
@@ -420,7 +420,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
World::getWorld()->isFogEnabled())
{
PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00);
- m_post_processing->renderFog();
+ renderLightsScatter(pointlightcount);
PROFILER_POP_CPU_MARKER();
}
diff --git a/src/graphics/render_lighting.cpp b/src/graphics/render_lighting.cpp
index 0d0ac9a6e..32749a468 100644
--- a/src/graphics/render_lighting.cpp
+++ b/src/graphics/render_lighting.cpp
@@ -185,3 +185,38 @@ void IrrDriver::renderSSAO()
m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_HALF1_R), irr_driver->getFBO(FBO_HALF2_R));
}
+
+void IrrDriver::renderLightsScatter(unsigned pointlightcount)
+{
+ getFBO(FBO_HALF1).Bind();
+ glClearColor(0., 0., 0., 0.);
+ glClear(GL_COLOR_BUFFER_BIT);
+ m_post_processing->renderFog();
+
+ glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_ONE, GL_ONE);
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+
+ const Track * const track = World::getWorld()->getTrack();
+
+ const float start = track->getFogStart();
+ const video::SColor tmpcol = track->getFogColor();
+ core::vector3df col(1., 1., 1.);
+
+ glUseProgram(LightShader::PointLightScatterShader::getInstance()->Program);
+ glBindVertexArray(LightShader::PointLightScatterShader::getInstance()->vao);
+
+ LightShader::PointLightScatterShader::getInstance()->SetTextureUnits(irr_driver->getDepthStencilTexture());
+ LightShader::PointLightScatterShader::getInstance()->setUniforms(1. / (40. * start), col);
+
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, pointlightcount);
+
+ glDisable(GL_BLEND);
+ m_post_processing->renderGaussian6Blur(getFBO(FBO_HALF1), getFBO(FBO_HALF2), 5., 5.);
+
+ glEnable(GL_BLEND);
+ getFBO(FBO_COLORS).Bind();
+ m_post_processing->renderPassThrough(getRenderTargetTexture(RTT_HALF1));
+}
\ No newline at end of file
diff --git a/src/graphics/render_skybox.cpp b/src/graphics/render_skybox.cpp
index 0016016f2..dca9dd889 100644
--- a/src/graphics/render_skybox.cpp
+++ b/src/graphics/render_skybox.cpp
@@ -538,6 +538,7 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
core::matrix4 transform = translate * scale;
core::matrix4 invtransform;
transform.getInverse(invtransform);
+ glDisable(GL_BLEND);
glUseProgram(MeshShader::SkyboxShader::getInstance()->Program);
MeshShader::SkyboxShader::getInstance()->setUniforms(transform);
diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp
index 0093dd2f7..9b3f4d5af 100644
--- a/src/graphics/shaders.cpp
+++ b/src/graphics/shaders.cpp
@@ -1468,6 +1468,41 @@ namespace LightShader
glVertexAttribDivisorARB(attrib_Color, 1);
glVertexAttribDivisorARB(attrib_Radius, 1);
}
+
+ PointLightScatterShader::PointLightScatterShader()
+ {
+ Program = LoadProgram(OBJECT,
+ GL_VERTEX_SHADER, file_manager->getAsset("shaders/pointlight.vert").c_str(),
+ GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
+ GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/pointlightscatter.frag").c_str());
+
+ AssignUniforms("density", "fogcol");
+ AssignSamplerNames(Program, 0, "dtex");
+
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, PointLightShader::getInstance()->vbo);
+
+ GLuint attrib_Position = glGetAttribLocation(Program, "Position");
+ GLuint attrib_Color = glGetAttribLocation(Program, "Color");
+ GLuint attrib_Energy = glGetAttribLocation(Program, "Energy");
+ GLuint attrib_Radius = glGetAttribLocation(Program, "Radius");
+
+ glEnableVertexAttribArray(attrib_Position);
+ glVertexAttribPointer(attrib_Position, 3, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), 0);
+ glEnableVertexAttribArray(attrib_Energy);
+ glVertexAttribPointer(attrib_Energy, 1, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(3 * sizeof(float)));
+ glEnableVertexAttribArray(attrib_Color);
+ glVertexAttribPointer(attrib_Color, 3, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(4 * sizeof(float)));
+ glEnableVertexAttribArray(attrib_Radius);
+ glVertexAttribPointer(attrib_Radius, 1, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(7 * sizeof(float)));
+
+ glVertexAttribDivisorARB(attrib_Position, 1);
+ glVertexAttribDivisorARB(attrib_Energy, 1);
+ glVertexAttribDivisorARB(attrib_Color, 1);
+ glVertexAttribDivisorARB(attrib_Radius, 1);
+ }
}
@@ -1712,7 +1747,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian6h.frag").c_str());
- AssignUniforms("pixel");
+ AssignUniforms("pixel", "sigma");
AssignSamplerNames(Program, 0, "tex");
}
@@ -1762,7 +1797,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian6v.frag").c_str());
- AssignUniforms("pixel");
+ AssignUniforms("pixel", "sigma");
AssignSamplerNames(Program, 0, "tex");
}
@@ -1862,7 +1897,7 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/fog.frag").c_str());
- AssignUniforms("fogmax", "startH", "endH", "start", "end", "col");
+ AssignUniforms("density", "col");
AssignSamplerNames(Program, 0, "tex");
}
diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp
index 2c1928cd6..3088e6b2c 100644
--- a/src/graphics/shaders.hpp
+++ b/src/graphics/shaders.hpp
@@ -328,6 +328,14 @@ namespace LightShader
GLuint vao;
PointLightShader();
};
+
+ class PointLightScatterShader : public ShaderHelperSingleton, public TextureRead
+ {
+ public:
+ GLuint vbo;
+ GLuint vao;
+ PointLightScatterShader();
+ };
}
namespace ParticleShader
@@ -456,7 +464,7 @@ public:
ComputeGaussian17TapHShader();
};
-class Gaussian6HBlurShader : public ShaderHelperSingleton, public TextureRead
+class Gaussian6HBlurShader : public ShaderHelperSingleton, public TextureRead
{
public:
Gaussian6HBlurShader();
@@ -489,7 +497,7 @@ public:
};
-class Gaussian6VBlurShader : public ShaderHelperSingleton, public TextureRead
+class Gaussian6VBlurShader : public ShaderHelperSingleton, public TextureRead
{
public:
Gaussian6VBlurShader();
@@ -550,7 +558,7 @@ public:
SSAOShader();
};
-class FogShader : public ShaderHelperSingleton, public TextureRead
+class FogShader : public ShaderHelperSingleton, public TextureRead
{
public:
FogShader();
diff --git a/supertuxkart.project b/supertuxkart.project
new file mode 100644
index 000000000..829e4235f
--- /dev/null
+++ b/supertuxkart.project
@@ -0,0 +1,2164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ make clean
+ make
+
+
+
+ None
+ $(WorkspacePath)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ make clean
+ make
+
+
+
+ None
+ $(WorkspacePath)
+
+
+
+
+
+
+
+
+
+
+
+
+
+