]> git.mxchange.org Git - flightgear.git/commitdiff
Shadow map size settable at run-time. It needs to be a power of two. Now needs a...
authorFrederic Bouvier <fredfgfs01@free.fr>
Fri, 30 Mar 2012 20:30:26 +0000 (22:30 +0200)
committerFrederic Bouvier <fredfgfs01@free.fr>
Fri, 30 Mar 2012 20:30:26 +0000 (22:30 +0200)
src/Main/CameraGroup.cxx
src/Main/CameraGroup.hxx
src/Main/renderer.cxx
src/Main/renderer.hxx

index 2795191a8c575190308c9ceb69f29900c130b609..0b676633f93f9018d533280537b0ab520bffe7c9 100644 (file)
@@ -246,6 +246,14 @@ osg::Camera* CameraInfo::getCamera(CameraKind k) const
     return ii->second.camera.get();
 }
 
+osg::Texture2D* CameraInfo::getBuffer(RenderBufferInfo::Kind k) const
+{
+    RenderBufferMap::const_iterator ii = buffers.find(k);
+    if (ii == buffers.end())
+        return 0;
+    return ii->second.texture.get();
+}
+
 int CameraInfo::getMainSlaveIndex() const
 {
     return cameras.find( MAIN_CAMERA )->second.slaveIndex;
index 5877429d5c621916d2f2d8be12ab5f3d091fd376..606bfc3477355d3335cb20e1bdb43a54d1300ce2 100644 (file)
@@ -158,7 +158,7 @@ struct CameraInfo : public osg::Referenced
         */
        RenderBufferMap buffers;
        void addBuffer(RenderBufferInfo::Kind k, osg::Texture2D* tex, float scale = 1.0 ) { buffers[k] = RenderBufferInfo(tex,scale); }
-       osg::Texture2D* getBuffer(RenderBufferInfo::Kind k) { return buffers[k].texture.get(); }
+       osg::Texture2D* getBuffer(RenderBufferInfo::Kind k) const;
 
     osg::ref_ptr<osg::TexGen> shadowTexGen[4];
 
index db17e0a8664c3c1f240417eceb031054c7b051a9..f7198fb9a80298146021031ba9633871a7f36cd9 100644 (file)
@@ -446,11 +446,19 @@ FGRenderer::splashinit( void ) {
     fgSetDouble("/sim/startup/splash-alpha", 1.0);
 }
 
+class ShadowMapSizeListener : public SGPropertyChangeListener {
+public:
+    virtual void valueChanged(SGPropertyNode* node) {
+        globals->get_renderer()->updateShadowMapSize(node->getIntValue());
+    }
+};
+
 void
 FGRenderer::init( void )
 {
        _classicalRenderer = !fgGetBool("/sim/rendering/rembrandt", false);
     _shadowMapSize    = fgGetInt( "/sim/rendering/shadows/map-size", 4096 );
+    fgAddChangeListener( new ShadowMapSizeListener, "/sim/rendering/shadows/map-size" );
     _scenery_loaded   = fgGetNode("/sim/sceneryloaded", true);
     _scenery_override = fgGetNode("/sim/sceneryloaded-override", true);
     _panel_hotspots   = fgGetNode("/sim/panel-hotspots", true);
@@ -856,7 +864,7 @@ void FGRenderer::updateShadowCamera(const flightgear::CameraInfo* info, const os
             updateShadowCascade(info, camera, grp, 0, left, right, bottom, top, zNear, 1.0, 5.0/zNear);
             updateShadowCascade(info, camera, grp, 1, left, right, bottom, top, zNear, 5.0/zNear,50.0/zNear);
             updateShadowCascade(info, camera, grp, 2, left, right, bottom, top, zNear, 50.0/zNear,512.0/zNear);
-            updateShadowCascade(info, camera, grp, 3, left, right, bottom, top, zNear, 512.0/zNear,10000.0/zNear);
+            updateShadowCascade(info, camera, grp, 3, left, right, bottom, top, zNear, 512.0/zNear,5000.0/zNear);
             {
             osg::Camera* cascade = static_cast<osg::Camera*>( mainShadowCamera );
             osg::Matrixd &viewMatrix = cascade->getViewMatrix();
@@ -872,6 +880,57 @@ void FGRenderer::updateShadowCamera(const flightgear::CameraInfo* info, const os
     }
 }
 
+void FGRenderer::updateShadowMapSize(int mapSize)
+{
+    if ( ((~( mapSize-1 )) & mapSize) != mapSize ) {
+        SG_LOG( SG_VIEW, SG_ALERT, "Map size is not a power of two" );
+        return;
+    }
+    for (   CameraGroup::CameraIterator ii = CameraGroup::getDefault()->camerasBegin();
+            ii != CameraGroup::getDefault()->camerasEnd();
+            ++ii )
+    {
+        CameraInfo* info = ii->get();
+        Camera* camera = info->getCamera(SHADOW_CAMERA);
+        if (camera == 0) continue;
+
+        Texture2D* tex = info->getBuffer(RenderBufferInfo::SHADOW_BUFFER);
+        if (tex == 0) continue;
+
+        tex->setTextureSize( mapSize, mapSize );
+        tex->dirtyTextureObject();
+
+        Viewport* vp = camera->getViewport();
+        vp->width() = mapSize;
+        vp->height() = mapSize;
+
+        osgViewer::Renderer* renderer
+            = static_cast<osgViewer::Renderer*>(camera->getRenderer());
+        for (int i = 0; i < 2; ++i) {
+            osgUtil::SceneView* sceneView = renderer->getSceneView(i);
+            sceneView->getRenderStage()->setFrameBufferObject(0);
+            sceneView->getRenderStage()->setCameraRequiresSetUp(true);
+            if (sceneView->getRenderStageLeft()) {
+                sceneView->getRenderStageLeft()->setFrameBufferObject(0);
+                sceneView->getRenderStageLeft()->setCameraRequiresSetUp(true);
+            }
+            if (sceneView->getRenderStageRight()) {
+                sceneView->getRenderStageRight()->setFrameBufferObject(0);
+                sceneView->getRenderStageRight()->setCameraRequiresSetUp(true);
+            }
+        }
+
+        int cascadeSize = mapSize / 2;
+               Group* grp = camera->getChild(0)->asGroup();
+               for (int i = 0; i < 4; ++i ) {
+            Camera* cascadeCam = static_cast<Camera*>( grp->getChild(i) );
+            cascadeCam->setViewport( int( i / 2 ) * cascadeSize, (i & 1) * cascadeSize, cascadeSize, cascadeSize );
+        }
+
+        _shadowMapSize = mapSize;
+    }
+}
+
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
 
@@ -1050,7 +1109,7 @@ const char *fog_frag_src = ""
 
 osg::Camera* FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc )
 {
-    SG_LOG( SG_INPUT, SG_ALERT, "Harmless warning messages on effects not found beyond this point" );
+    SG_LOG( SG_VIEW, SG_ALERT, "Harmless warning messages on effects not found beyond this point" );
     osg::Camera* camera = new osg::Camera;
        info->addCamera(flightgear::LIGHTING_CAMERA, camera );
 
@@ -1236,7 +1295,7 @@ osg::Camera* FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* in
 
     camera->addChild( lightingGroup );
 
-    SG_LOG( SG_INPUT, SG_ALERT, "End of harmless warning messages on effects not found" );
+    SG_LOG( SG_VIEW, SG_ALERT, "End of harmless warning messages on effects not found" );
 
        return camera;
 }
index 0db0fa5d7517c298189dbb561ce7a215fb48ce63..8197455381331c72456816ea84fc47f9c0f04d3d 100644 (file)
@@ -105,6 +105,7 @@ public:
                                    const osg::Matrix& view, const osg::Matrix& projection, osg::GraphicsContext* gc);
 
     void updateShadowCamera(const flightgear::CameraInfo* info, const osg::Vec3d& position);
+    void updateShadowMapSize(int mapSize);
 
     SGSky* getSky() const { return _sky; }