diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc index c1f87182e48c09e4f9102a56904117dac0bfab63..a9ddbc4cd9f8fc7e7d235efae0c8ce390c422d71 100644 --- a/modules/gfx/src/impl/scene_fx.cc +++ b/modules/gfx/src/impl/scene_fx.cc @@ -224,6 +224,11 @@ void SceneFX::Preprocess() } } +bool SceneFX::WillPostprocess() const +{ + return shadow_flag || amb_occl_flag || depth_dark_flag || use_beacon; +} + void SceneFX::Postprocess() { if(!OST_GL_VERSION_2_0) return; @@ -235,10 +240,7 @@ void SceneFX::Postprocess() #endif } - if(!shadow_flag && !amb_occl_flag && !depth_dark_flag && !use_beacon) { - // no postprocessing is needed - return; - } + if(!WillPostprocess()) return; Viewport vp=Scene::Instance().GetViewport(); @@ -329,6 +331,18 @@ void SceneFX::Postprocess() glUniform1i(glGetUniformLocation(cpr,"dark_flag"),0); } + GLint fog; + glGetIntegerv(GL_FOG,&fog); + float znear=Scene::Instance().GetNear(); + float zfar=Scene::Instance().GetFar(); + float fnear=znear+Scene::Instance().GetFogNearOffset(); + float ffar=zfar+Scene::Instance().GetFogFarOffset(); + glUniform1i(glGetUniformLocation(cpr,"fog_flag"),fog); + glUniform1f(glGetUniformLocation(cpr,"depth_near"),znear); + glUniform1f(glGetUniformLocation(cpr,"depth_far"),zfar); + glUniform1f(glGetUniformLocation(cpr,"fog_far"),ffar); + glUniform1f(glGetUniformLocation(cpr,"fog_scale"),1.0f/(ffar-fnear)); + if(use_beacon) { prep_beacon(); } diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh index 3b8e1fa388b67ea0c51be27676b437875c0e7aa6..ad8d2a787c57a7b4e9eb1433fd5d8e1f4c63d173 100644 --- a/modules/gfx/src/impl/scene_fx.hh +++ b/modules/gfx/src/impl/scene_fx.hh @@ -53,6 +53,9 @@ public: void Preprocess(); // assumes scene has been drawn in the active framebuffer void Postprocess(); + + // returns true if the post-processing will run + bool WillPostprocess() const; void DrawTex(unsigned int w, unsigned int h, GLuint texid); diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc index 2a5e91ce25fa41c121ae12ecca5a6a2f08a82e68..3ed15cac334785fbb45e4d1b63fb91d62c70f599 100644 --- a/modules/gfx/src/shader.cc +++ b/modules/gfx/src/shader.cc @@ -28,6 +28,7 @@ #include <ost/platform.hh> #include <ost/log.hh> +#include "impl/scene_fx.hh" #include "glext_include.hh" #include "shader.hh" @@ -366,7 +367,11 @@ void Shader::UpdateState() glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE,&bresult); LOG_TRACE("setting two_sided flag to " << bresult); glUniform1i(glGetUniformLocation(current_program_,"two_sided_flag"),bresult); - glGetIntegerv(GL_FOG,&result); + if(impl::SceneFX::Instance().WillPostprocess()) { + result=0; + } else { + glGetIntegerv(GL_FOG,&result); + } LOG_TRACE("setting fog flag to " << result); glUniform1i(glGetUniformLocation(current_program_,"fog_flag"),result); glDisable(GL_COLOR_MATERIAL); diff --git a/modules/gfx/src/shader/scenefx_fs.glsl b/modules/gfx/src/shader/scenefx_fs.glsl index cb5c2313c77dced05f81fdd4854704ebbb4b9a6c..e328d2d086842e680c79329ab1fdaafd204d9cea 100644 --- a/modules/gfx/src/shader/scenefx_fs.glsl +++ b/modules/gfx/src/shader/scenefx_fs.glsl @@ -13,6 +13,11 @@ uniform float occl_mult; uniform bool dark_flag; uniform sampler2D dark_map; uniform float dark_mult; +uniform bool fog_flag; +uniform float depth_near; +uniform float depth_far; +uniform float fog_far; +uniform float fog_scale; // gl_TexCoord[0] comes from scenefx_vs, i.e. from post processing @@ -55,6 +60,15 @@ void main() if(dark_flag) { dark_factor=max(0.0,1.0-dark_mult*(1.0-texture2D(dark_map,gl_TexCoord[0].xy).r)); } - - gl_FragColor.rgb = shadow_factor*occl_factor*dark_factor*scene_color.rgb; + + float fog=1.0; + if(fog_flag) { + float z = 2.0*depth_near*depth_far/(-(depth*2.0-1.0)*(depth_far-depth_near)+depth_far+depth_near); + fog = clamp((fog_far-z) * fog_scale, 0.0, 1.0); + } + + gl_FragColor.rgb = mix(gl_Fog.color.rgb, + shadow_factor*occl_factor*dark_factor*scene_color.rgb, + fog); } +