From 044e0a829a812748934893d941d2bc3e09ecc553 Mon Sep 17 00:00:00 2001
From: scrawl <scrawl@baseoftrash.de>
Date: Tue, 16 Feb 2016 22:32:59 +0100
Subject: [PATCH] Add fog

---
 apps/openmw/mwrender/characterpreview.cpp | 7 +++++++
 apps/openmw/mwrender/localmap.cpp         | 7 ++++++-
 files/shaders/objects_fragment.glsl       | 7 ++++++-
 files/shaders/objects_vertex.glsl         | 3 +++
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp
index 2588540540..1c9c3be4bd 100644
--- a/apps/openmw/mwrender/characterpreview.cpp
+++ b/apps/openmw/mwrender/characterpreview.cpp
@@ -2,6 +2,7 @@
 
 #include <iostream>
 
+#include <osg/Fog>
 #include <osg/Texture2D>
 #include <osg/Camera>
 #include <osg/PositionAttitudeTransform>
@@ -102,6 +103,12 @@ namespace MWRender
         stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
         stateset->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
         stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
+        // assign large value to effectively turn off fog
+        // shaders don't respect glDisable(GL_FOG)
+        osg::ref_ptr<osg::Fog> fog (new osg::Fog);
+        fog->setStart(10000000);
+        fog->setEnd(10000000);
+        stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
 
         osg::ref_ptr<osg::LightModel> lightmodel = new osg::LightModel;
         lightmodel->setAmbientIntensity(osg::Vec4(0.25, 0.25, 0.25, 1.0));
diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp
index fd224ba415..be477735f8 100644
--- a/apps/openmw/mwrender/localmap.cpp
+++ b/apps/openmw/mwrender/localmap.cpp
@@ -180,7 +180,12 @@ osg::ref_ptr<osg::Camera> LocalMap::createOrthographicCamera(float x, float y, f
     stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
     stateset->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
     stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
-    stateset->setMode(GL_FOG, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
+    // assign large value to effectively turn off fog
+    // shaders don't respect glDisable(GL_FOG)
+    osg::ref_ptr<osg::Fog> fog (new osg::Fog);
+    fog->setStart(10000000);
+    fog->setEnd(10000000);
+    stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
 
     osg::ref_ptr<osg::LightModel> lightmodel = new osg::LightModel;
     lightmodel->setAmbientIntensity(osg::Vec4(0.3f, 0.3f, 0.3f, 1.f));
diff --git a/files/shaders/objects_fragment.glsl b/files/shaders/objects_fragment.glsl
index 9b42c30a79..288760229f 100644
--- a/files/shaders/objects_fragment.glsl
+++ b/files/shaders/objects_fragment.glsl
@@ -5,11 +5,16 @@ uniform sampler2D diffuseMap;
 varying vec2 diffuseMapUV;
 #endif
 
+varying float depth;
+
 void main()
 {
 #if @diffuseMap
     gl_FragData[0] = texture2D(diffuseMap, diffuseMapUV);
 #else
-    gl_FragData[0] = vec4(1,1,1,1);
+    gl_FragData[0] = vec4(1.0, 1.0, 1.0, 1.0);
 #endif
+
+    float fogValue = clamp((depth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
+    gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
 }
diff --git a/files/shaders/objects_vertex.glsl b/files/shaders/objects_vertex.glsl
index 17e8f3fc42..47ae205724 100644
--- a/files/shaders/objects_vertex.glsl
+++ b/files/shaders/objects_vertex.glsl
@@ -3,10 +3,13 @@
 #if @diffuseMap
 varying vec2 diffuseMapUV;
 #endif
+
+varying float depth;
     
 void main(void)
 {
     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+    depth = gl_Position.z;
 
 #if @diffuseMap
     diffuseMapUV = gl_MultiTexCoord@diffuseMapUV.xy;