From 6d0cacc0a32fdb84635c3216e913375e6a6489f1 Mon Sep 17 00:00:00 2001
From: Frederic Bouvier <fredfgfs01@free.fr>
Date: Wed, 27 Jun 2012 19:37:38 +0200
Subject: [PATCH] Get rid of TexGen magic and do the projective texturing for
 shadow mapping ourself

---
 src/Viewer/CameraGroup.hxx |  8 +++++---
 src/Viewer/renderer.cxx    | 20 ++++++++++----------
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/Viewer/CameraGroup.hxx b/src/Viewer/CameraGroup.hxx
index 9bc570036..1bdcd02de 100644
--- a/src/Viewer/CameraGroup.hxx
+++ b/src/Viewer/CameraGroup.hxx
@@ -100,6 +100,10 @@ struct CameraInfo : public osg::Referenced
           du( new osg::Uniform( "fg_du",osg::Vec4() ) ),
           dv( new osg::Uniform( "fg_dv",osg::Vec4() ) )
     {
+        shadowMatrix[0] = new osg::Uniform("fg_ShadowMatrix_0", osg::Matrixf());
+        shadowMatrix[1] = new osg::Uniform("fg_ShadowMatrix_1", osg::Matrixf());
+        shadowMatrix[2] = new osg::Uniform("fg_ShadowMatrix_2", osg::Matrixf());
+        shadowMatrix[3] = new osg::Uniform("fg_ShadowMatrix_3", osg::Matrixf());
     }
 
     /** Update and resize cameras
@@ -147,10 +151,7 @@ struct CameraInfo : public osg::Referenced
     void addBuffer(const std::string& k, osg::Texture2D* tex, float scale = 1.0 ) { buffers[k] = RenderBufferInfo(tex,scale); }
     osg::Texture2D* getBuffer(const std::string& k) const;
 
-    osg::ref_ptr<osg::TexGen> shadowTexGen[4];
-
     osg::ref_ptr<osg::Uniform> bufferSize;
-    //osg::ref_ptr<osg::Uniform> bloomOffset[2];
     osg::ref_ptr<osg::Uniform> projInverse;
     osg::ref_ptr<osg::Uniform> viewInverse;
     osg::ref_ptr<osg::Uniform> view;
@@ -158,6 +159,7 @@ struct CameraInfo : public osg::Referenced
     osg::ref_ptr<osg::Uniform> worldPosGeod;
     osg::ref_ptr<osg::Uniform> du;
     osg::ref_ptr<osg::Uniform> dv;
+    osg::ref_ptr<osg::Uniform> shadowMatrix[4];
 
     void setMatrices( osg::Camera* c );
 
diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx
index 1314c7f28..981fa549e 100644
--- a/src/Viewer/renderer.cxx
+++ b/src/Viewer/renderer.cxx
@@ -719,18 +719,15 @@ public:
                 for (int i = 0; i < 4; ++i ) {
                     if (!grp->getValue(i))
                         continue;
-                    osg::TexGen* shadowTexGen = info->shadowTexGen[i];
-                    shadowTexGen->setMode(osg::TexGen::EYE_LINEAR);
 
                     osg::Camera* cascadeCam = static_cast<osg::Camera*>( grp->getChild(i) );
-                    // compute the matrix which takes a vertex from view coords into tex coords
-                    shadowTexGen->setPlanesFromMatrix(  cascadeCam->getProjectionMatrix() *
-                                                        osg::Matrix::translate(1.0,1.0,1.0) *
-                                                        osg::Matrix::scale(0.5f,0.5f,0.5f) );
+                    osg::Matrixf shadowMatrix = camera->getInverseViewMatrix() *
+                                                cascadeCam->getViewMatrix() *
+                                                cascadeCam->getProjectionMatrix() *
+                                                osg::Matrix::translate(1.0, 1.0, 1.0) *
+                                                osg::Matrix::scale(0.5f, 0.5f, 0.5f);
 
-                    osg::RefMatrix * refMatrix = new osg::RefMatrix( cascadeCam->getInverseViewMatrix() * *cv->getModelViewMatrix() );
-
-                    cv->getRenderStage()->getPositionalStateContainer()->addPositionedTextureAttribute( i+1, refMatrix, shadowTexGen );
+                    info->shadowMatrix[i]->set( shadowMatrix );
                 }
             }
             // Render saved transparent render bins
@@ -876,7 +873,6 @@ osg::Camera* FGRenderer::buildDeferredShadowCamera( CameraInfo* info, osg::Graph
         osg::Camera* cascadeCam = createShadowCascadeCamera( i, _shadowMapSize/2 );
         cascadeCam->addChild( mDeferredRealRoot.get() );
         shadowSwitch->addChild( cascadeCam );
-        info->shadowTexGen[i] = new osg::TexGen;
     }
     if (fgGetBool("/sim/rendering/shadows/enabled", true))
         shadowSwitch->setAllChildrenOn();
@@ -1123,6 +1119,10 @@ FGRenderer::buildDeferredFullscreenCamera( flightgear::CameraInfo* info, const F
     ss->addUniform( info->bufferSize );
     ss->addUniform( info->worldPosCart );
     ss->addUniform( info->worldPosGeod );
+    ss->addUniform( info->shadowMatrix[0] );
+    ss->addUniform( info->shadowMatrix[1] );
+    ss->addUniform( info->shadowMatrix[2] );
+    ss->addUniform( info->shadowMatrix[3] );
     ss->addUniform( _ambientFactor );
     ss->addUniform( _sunDiffuse );
     ss->addUniform( _sunSpecular );