]> git.mxchange.org Git - flightgear.git/blobdiff - src/Viewer/renderer.cxx
commradio: improvements for atis speech
[flightgear.git] / src / Viewer / renderer.cxx
index 9a0817c7dccddec41896bfc3e7d6f6764540553c..9728f0f72ac0757c255a8d6ac75e5d3b2efea667 100644 (file)
@@ -86,9 +86,6 @@
 #include <simgear/timing/sg_time.hxx>
 #include <simgear/ephemeris/ephemeris.hxx>
 #include <simgear/math/sg_random.h>
-#ifdef FG_JPEG_SERVER
-#include <simgear/screen/jpgfactory.hxx>
-#endif
 
 #include <Time/light.hxx>
 #include <Time/light.hxx>
@@ -221,9 +218,12 @@ public:
     glPushAttrib(GL_ALL_ATTRIB_BITS);
     glPushClientAttrib(~0u);
       
-    HUD *hud = static_cast<HUD*>(globals->get_subsystem("hud"));
-    hud->draw(state);
-
+    // HUD can be NULL
+      HUD *hud = static_cast<HUD*>(globals->get_subsystem("hud"));
+      if (hud) {
+          hud->draw(state);
+      }
+      
     glPopClientAttrib();
     glPopAttrib();
   }
@@ -255,6 +255,11 @@ public:
     osg::Light* light = lightSource->getLight();
     
     FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
+      if (!l) {
+          // lighting is down during re-init
+          return;
+      }
+      
     if (_isSun) {
       light->setAmbient(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
       light->setDiffuse(Vec4(1.0f, 1.0f, 1.0f, 1.0f));
@@ -378,21 +383,6 @@ public:
 
 bool FGScenerySwitchCallback::scenery_enabled = false;
 
-static osg::ref_ptr<osg::FrameStamp> mFrameStamp = new osg::FrameStamp;
-static osg::ref_ptr<SGUpdateVisitor> mUpdateVisitor= new SGUpdateVisitor;
-
-static osg::ref_ptr<osg::Group> mRealRoot = new osg::Group;
-static osg::ref_ptr<osg::Group> mDeferredRealRoot = new osg::Group;
-
-static osg::ref_ptr<osg::Group> mRoot = new osg::Group;
-
-#ifdef FG_JPEG_SERVER
-static void updateRenderer()
-{
-    globals->get_renderer()->update();
-}
-#endif
-
 FGRenderer::FGRenderer() :
     _sky(NULL),
     _ambientFactor( new osg::Uniform( "fg_SunAmbientColor", osg::Vec4f() ) ),
@@ -406,13 +396,17 @@ FGRenderer::FGRenderer() :
     _shadowDistances( new osg::Uniform( "fg_ShadowDistances", osg::Vec4f(5.0, 50.0, 500.0, 5000.0 ) ) ),
     _depthInColor( new osg::Uniform( "fg_DepthInColor", false ) )
 {
-#ifdef FG_JPEG_SERVER
-   jpgRenderFrame = updateRenderer;
-#endif
-    
     // it's not the real root, whatever that means
-    mRoot->setName("fakeRoot"); 
+    _root = new osg::Group;
+    _root->setName("fakeRoot");
 
+    _updateVisitor = new SGUpdateVisitor;
+  
+  // when Rembrandt is enabled, we use this group to access the whole
+  // scene. Since the only child is the _viewerSceneRoot, we could
+  // simply copy the reference, we don't need the additional group.
+    _deferredRealRoot = new osg::Group;
+    
    _numCascades = 4;
    _cascadeFar[0] = 5.f;
    _cascadeFar[1] = 50.f;
@@ -422,9 +416,16 @@ FGRenderer::FGRenderer() :
 
 FGRenderer::~FGRenderer()
 {
-#ifdef FG_JPEG_SERVER
-   jpgRenderFrame = NULL;
-#endif
+    SGPropertyChangeListenerVec::iterator i = _listeners.begin();
+    for (; i != _listeners.end(); ++i) {
+        delete *i;
+    }
+    
+    // replace the viewer's scene completely
+    if (getViewer()) {
+        getViewer()->setSceneData(new osg::Group);
+    }
+    
     delete _sky;
 }
 
@@ -432,15 +433,20 @@ FGRenderer::~FGRenderer()
 // XXX This should be called "preinit" or something, as it initializes
 // critical parts of the scene graph in addition to the splash screen.
 void
-FGRenderer::splashinit( void ) {
+FGRenderer::splashinit( void )
+{
+    // important that we reset the viewer sceneData here, to ensure the reference
+    // time for everything is in sync; otherwise on reset the Viewer and
+    // GraphicsWindow clocks are out of sync.
     osgViewer::Viewer* viewer = getViewer();
     viewer->setName("osgViewer");
-    mRealRoot = dynamic_cast<osg::Group*>(viewer->getSceneData());
-    mRealRoot->setName("realRoot");
+    _viewerSceneRoot = new osg::Group;
+    _viewerSceneRoot->setName("viewerSceneRoot");
+    viewer->setSceneData(_viewerSceneRoot);
     
     ref_ptr<Node> splashNode = fgCreateSplashNode();
     if (_classicalRenderer) {
-        mRealRoot->addChild(splashNode.get());
+        _viewerSceneRoot->addChild(splashNode.get());
     } else {
         for (   CameraGroup::CameraIterator ii = CameraGroup::getDefault()->camerasBegin();
                 ii != CameraGroup::getDefault()->camerasEnd();
@@ -453,11 +459,13 @@ FGRenderer::splashinit( void ) {
             camera->addChild(splashNode.get());
         }
     }
-    mFrameStamp = viewer->getFrameStamp();
+    
+    _frameStamp = new osg::FrameStamp;
+    viewer->setFrameStamp(_frameStamp.get());
     // Scene doesn't seem to pass the frame stamp to the update
     // visitor automatically.
-    mUpdateVisitor->setFrameStamp(mFrameStamp.get());
-    viewer->setUpdateVisitor(mUpdateVisitor.get());
+    _updateVisitor->setFrameStamp(_frameStamp.get());
+    viewer->setUpdateVisitor(_updateVisitor.get());
     fgSetDouble("/sim/startup/splash-alpha", 1.0);
 }
 
@@ -489,23 +497,31 @@ public:
     }
 };
 
+void
+FGRenderer::addChangeListener(SGPropertyChangeListener* l, const char* path)
+{
+    _listeners.push_back(l);
+    fgAddChangeListener(l, path);
+}
+                                    
 void
 FGRenderer::init( void )
 {
-    eventHandler = new FGEventHandler();
+    if (!eventHandler)
+        eventHandler = new FGEventHandler();
 
     sgUserDataInit( globals->get_props() );
 
     _classicalRenderer = !fgGetBool("/sim/rendering/rembrandt/enabled", false);
     _shadowMapSize    = fgGetInt( "/sim/rendering/shadows/map-size", 4096 );
-    fgAddChangeListener( new ShadowMapSizeListener, "/sim/rendering/shadows/map-size" );
-    fgAddChangeListener( new ShadowEnabledListener, "/sim/rendering/shadows/enabled" );
+    addChangeListener( new ShadowMapSizeListener, "/sim/rendering/shadows/map-size" );
+    addChangeListener( new ShadowEnabledListener, "/sim/rendering/shadows/enabled" );
     ShadowRangeListener* srl = new ShadowRangeListener;
-    fgAddChangeListener(srl, "/sim/rendering/shadows/cascade-far-m[0]");
+    addChangeListener(srl, "/sim/rendering/shadows/cascade-far-m[0]");
     fgAddChangeListener(srl, "/sim/rendering/shadows/cascade-far-m[1]");
     fgAddChangeListener(srl, "/sim/rendering/shadows/cascade-far-m[2]");
     fgAddChangeListener(srl, "/sim/rendering/shadows/cascade-far-m[3]");
-    fgAddChangeListener(new ShadowNumListener, "/sim/rendering/shadows/num-cascades");
+    addChangeListener(new ShadowNumListener, "/sim/rendering/shadows/num-cascades");
     _numCascades = fgGetInt("/sim/rendering/shadows/num-cascades", 4);
     _cascadeFar[0] = fgGetFloat("/sim/rendering/shadows/cascade-far-m[0]", 5.0f);
     _cascadeFar[1] = fgGetFloat("/sim/rendering/shadows/cascade-far-m[1]", 50.0f);
@@ -534,12 +550,10 @@ FGRenderer::init( void )
     _ysize         = fgGetNode("/sim/startup/ysize", true);
     _splash_alpha  = fgGetNode("/sim/startup/splash-alpha", true);
 
-    _skyblend             = fgGetNode("/sim/rendering/skyblend", true);
     _point_sprites        = fgGetNode("/sim/rendering/point-sprites", true);
     _enhanced_lighting    = fgGetNode("/sim/rendering/enhanced-lighting", true);
     _distance_attenuation = fgGetNode("/sim/rendering/distance-attenuation", true);
     _horizon_effect       = fgGetNode("/sim/rendering/horizon-effect", true);
-    _textures             = fgGetNode("/sim/rendering/textures", true);
 
     _altitude_ft = fgGetNode("/position/altitude-ft", true);
 
@@ -587,7 +601,6 @@ FGRenderer::init( void )
 
     if (!_classicalRenderer) {
         eventHandler->setChangeStatsCameraRenderOrder( true );
-        _sky->set_minimum_sky_visibility( 0.0 ); // A black sky appears for below that
     }
 }
 
@@ -597,9 +610,7 @@ void installCullVisitor(Camera* camera)
         = static_cast<osgViewer::Renderer*>(camera->getRenderer());
     for (int i = 0; i < 2; ++i) {
         osgUtil::SceneView* sceneView = renderer->getSceneView(i);
-#if SG_OSG_VERSION_LESS_THAN(3,0,0)
-        sceneView->setCullVisitor(new simgear::EffectCullVisitor);
-#else
+
         osg::ref_ptr<osgUtil::CullVisitor::Identifier> identifier;
         identifier = sceneView->getCullVisitor()->getIdentifier();
         sceneView->setCullVisitor(new simgear::EffectCullVisitor);
@@ -612,7 +623,7 @@ void installCullVisitor(Camera* camera)
         identifier = sceneView->getCullVisitorRight()->getIdentifier();
         sceneView->setCullVisitorRight(sceneView->getCullVisitor()->clone());
         sceneView->getCullVisitorRight()->setIdentifier(identifier.get());
-#endif
+
     }
 }
 
@@ -808,7 +819,7 @@ osg::Camera* FGRenderer::buildDeferredGeometryCamera( CameraInfo* info, osg::Gra
     osg::StateSet* ss = camera->getOrCreateStateSet();
     ss->addUniform( _depthInColor );
 
-    camera->addChild( mDeferredRealRoot.get() );
+    camera->addChild( _deferredRealRoot.get() );
 
     return camera;
 }
@@ -877,7 +888,7 @@ osg::Camera* FGRenderer::buildDeferredShadowCamera( CameraInfo* info, osg::Graph
 
     for (int i = 0; i < 4; ++i ) {
         osg::Camera* cascadeCam = createShadowCascadeCamera( i, _shadowMapSize/2 );
-        cascadeCam->addChild( mDeferredRealRoot.get() );
+        cascadeCam->addChild( _deferredRealRoot.get() );
         shadowSwitch->addChild( cascadeCam );
     }
     if (fgGetBool("/sim/rendering/shadows/enabled", true))
@@ -1087,7 +1098,6 @@ FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* info, osg::Grap
     buildAttachments(info, camera, stage->name, stage->attachments);
     camera->setDrawBuffer(GL_FRONT);
     camera->setReadBuffer(GL_FRONT);
-    camera->setClearColor( osg::Vec4( 0.5, 0.5, 0.5, 1. ) );
     camera->setClearMask( GL_COLOR_BUFFER_BIT );
     osg::StateSet* ss = camera->getOrCreateStateSet();
     ss->setAttribute( new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false) );
@@ -1293,6 +1303,9 @@ osg::Node*
 FGRenderer::buildLightingSkyCloudsPass(FGRenderingPipeline::Pass* pass)
 {
     Group* group = new Group;
+    group->setName("skyCloudsGroup");
+    group->setNodeMask(simgear::BACKGROUND_BIT);
+    
     StateSet* ss = group->getOrCreateStateSet();
     ss->setAttributeAndModes( new osg::ColorMask( true, true, true, false ), osg::StateAttribute::ON );
     group->addChild( _sky->getPreRoot() );
@@ -1319,7 +1332,7 @@ FGRenderer::buildLightingLightsPass(CameraInfo* info, FGRenderingPipeline::Pass*
     lightCam->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
     lightCam->setCullMask( simgear::MODELLIGHT_BIT | simgear::PANEL2D_BIT | simgear::PERMANENTLIGHT_BIT);
     lightCam->setInheritanceMask( osg::CullSettings::ALL_VARIABLES & ~osg::CullSettings::CULL_MASK );
-    lightCam->addChild( mDeferredRealRoot.get() );
+    lightCam->addChild( _deferredRealRoot.get() );
 
     return lightCam;
 }
@@ -1379,59 +1392,29 @@ CameraInfo* FGRenderer::buildCameraFromRenderingPipeline(FGRenderingPipeline* rp
     return info;
 }
 
-void
-FGRenderer::setupView( void )
+void FGRenderer::setupRoot()
 {
-    osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
-    osg::initNotifyLevel();
-
-    // The number of polygon-offset "units" to place between layers.  In
-    // principle, one is supposed to be enough.  In practice, I find that
-    // my hardware/driver requires many more.
-    osg::PolygonOffset::setUnitsMultiplier(1);
-    osg::PolygonOffset::setFactorMultiplier(1);
-
-// build the sky    
-    // The sun and moon diameters are scaled down numbers of the
-    // actual diameters. This was needed to fit both the sun and the
-    // moon within the distance to the far clip plane.
-    // Moon diameter:    3,476 kilometers
-    // Sun diameter: 1,390,000 kilometers
-    osg::ref_ptr<SGReaderWriterOptions> opt;
-    opt = SGReaderWriterOptions::fromPath(globals->get_fg_root());
-    opt->setPropertyNode(globals->get_props());
-    _sky->build( 80000.0, 80000.0,
-                  463.3, 361.8,
-                  *globals->get_ephem(),
-                  fgGetNode("/environment", true),
-                  opt.get());
-    
-    viewer->getCamera()
-        ->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+    osg::StateSet* stateSet = _root->getOrCreateStateSet();
     
-    osg::StateSet* stateSet = mRoot->getOrCreateStateSet();
-
     stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
     
     stateSet->setAttribute(new osg::Depth(osg::Depth::LESS));
     stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
-
-    stateSet->setAttribute(new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01));
-    stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
+    
     stateSet->setAttribute(new osg::BlendFunc);
     stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF);
-
+    
     stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
     
     // this will be set below
     stateSet->setMode(GL_NORMALIZE, osg::StateAttribute::OFF);
-
+    
     osg::Material* material = new osg::Material;
     stateSet->setAttribute(material);
     
     stateSet->setTextureAttribute(0, new osg::TexEnv);
     stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OFF);
-
+    
     osg::Hint* hint = new osg::Hint(GL_FOG_HINT, GL_DONT_CARE);
     hint->setUpdateCallback(new FGHintUpdateCallback("/sim/rendering/fog"));
     stateSet->setAttribute(hint);
@@ -1447,17 +1430,41 @@ FGRenderer::setupView( void )
     hint = new osg::Hint(GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE);
     hint->setUpdateCallback(new FGHintUpdateCallback("/sim/rendering/perspective-correction"));
     stateSet->setAttribute(hint);
+}
+                                    
+void
+FGRenderer::setupView( void )
+{
+    osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
+    osg::initNotifyLevel();
 
-    osg::Group* sceneGroup = new osg::Group;
-    sceneGroup->setName("rendererScene");
-    sceneGroup->addChild(globals->get_scenery()->get_scene_graph());
-    sceneGroup->setNodeMask(~simgear::BACKGROUND_BIT);
-
-    //sceneGroup->addChild(thesky->getCloudRoot());
-
-    stateSet = sceneGroup->getOrCreateStateSet();
-    stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
+    // The number of polygon-offset "units" to place between layers.  In
+    // principle, one is supposed to be enough.  In practice, I find that
+    // my hardware/driver requires many more.
+    osg::PolygonOffset::setUnitsMultiplier(1);
+    osg::PolygonOffset::setFactorMultiplier(1);
 
+    setupRoot();
+  
+// build the sky    
+    // The sun and moon diameters are scaled down numbers of the
+    // actual diameters. This was needed to fit both the sun and the
+    // moon within the distance to the far clip plane.
+    // Moon diameter:    3,476 kilometers
+    // Sun diameter: 1,390,000 kilometers
+    osg::ref_ptr<SGReaderWriterOptions> opt;
+    opt = SGReaderWriterOptions::fromPath(globals->get_fg_root());
+    opt->setPropertyNode(globals->get_props());
+    _sky->build( 80000.0, 80000.0,
+                  463.3, 361.8,
+                  *globals->get_ephem(),
+                  fgGetNode("/environment", true),
+                  opt.get());
+    
+    viewer->getCamera()
+        ->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+    
+  
     // need to update the light on every frame
     // OSG LightSource objects are rather confusing. OSG only supports
     // the 10 lights specified by OpenGL itself; if more than one
@@ -1468,16 +1475,17 @@ FGRenderer::setupView( void )
     // has the corresponding OpenGL light enabled: a LightSource will
     // affect geometry anywhere in the scene graph that has its light
     // number enabled in a state set. 
-    LightSource* lightSource = new LightSource;
+    osg::ref_ptr<LightSource> lightSource = new LightSource;
     lightSource->setName("FGLightSource");
     lightSource->getLight()->setDataVariance(Object::DYNAMIC);
     // relative because of CameraView being just a clever transform node
     lightSource->setReferenceFrame(osg::LightSource::RELATIVE_RF);
     lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
     lightSource->setUpdateCallback(new FGLightSourceUpdateCallback);
-    mRealRoot->addChild(lightSource);
+    _viewerSceneRoot->addChild(lightSource);
+    
     // we need a white diffuse light for the phase of the moon
-    osg::LightSource* sunLight = new osg::LightSource;
+    osg::ref_ptr<LightSource> sunLight = new osg::LightSource;
     sunLight->setName("sunLightSource");
     sunLight->getLight()->setDataVariance(Object::DYNAMIC);
     sunLight->getLight()->setLightNum(1);
@@ -1487,19 +1495,22 @@ FGRenderer::setupView( void )
     
     // Hang a StateSet above the sky subgraph in order to turn off
     // light 0
-    Group* skyGroup = new Group;
-    skyGroup->setName("rendererSkyParent");
+    Group* skyGroup = _sky->getPreRoot();
     StateSet* skySS = skyGroup->getOrCreateStateSet();
     skySS->setMode(GL_LIGHT0, StateAttribute::OFF);
-    skyGroup->addChild(_sky->getPreRoot());
     sunLight->addChild(skyGroup);
-    mRoot->addChild(sceneGroup);
-    if ( _classicalRenderer )
-        mRoot->addChild(sunLight);
     
-    // Clouds are added to the scene graph later
-    stateSet = globals->get_scenery()->get_scene_graph()->getOrCreateStateSet();
-    stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
+    if ( _classicalRenderer ) {
+        _root->addChild(sunLight);
+    }
+  
+    osg::Group* sceneGroup = globals->get_scenery()->get_scene_graph();
+    sceneGroup->setName("rendererScene");
+    sceneGroup->setNodeMask(~simgear::BACKGROUND_BIT);
+    _root->addChild(sceneGroup);
+  
+    // setup state-set for main scenery (including models and aircraft)
+    osg::StateSet* stateSet = sceneGroup->getOrCreateStateSet();
     stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
     stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
 
@@ -1536,23 +1547,24 @@ FGRenderer::setupView( void )
     osg::Switch* sw = new osg::Switch;
     sw->setName("scenerySwitch");
     sw->setUpdateCallback(new FGScenerySwitchCallback);
-    sw->addChild(mRoot.get());
-    mRealRoot->addChild(sw);
+    sw->addChild(_root.get());
+    _viewerSceneRoot->addChild(sw);
     // The clouds are attached directly to the scene graph root
     // because, in theory, they don't want the same default state set
     // as the rest of the scene. This may not be true in practice.
-       if ( _classicalRenderer ) {
-               mRealRoot->addChild(_sky->getCloudRoot());
-               mRealRoot->addChild(FGCreateRedoutNode());
-       }
+    if ( _classicalRenderer ) {
+      _viewerSceneRoot->addChild(_sky->getCloudRoot());
+      _viewerSceneRoot->addChild(FGCreateRedoutNode());
+    }
+  
     // Attach empty program to the scene root so that shader programs
     // don't leak into state sets (effects) that shouldn't have one.
-    stateSet = mRealRoot->getOrCreateStateSet();
+    stateSet = _viewerSceneRoot->getOrCreateStateSet();
     stateSet->setAttributeAndModes(new osg::Program, osg::StateAttribute::ON);
 
-    mDeferredRealRoot->addChild( mRealRoot.get() );
-
-    DeletionManager::install(mRealRoot.get());
+    if ( !_classicalRenderer ) {
+        _deferredRealRoot->addChild( _viewerSceneRoot.get() );
+    }
 }
 
 // Update all Visuals (redraws anything graphics related)
@@ -1605,124 +1617,89 @@ FGRenderer::update( ) {
   
     osg::Camera *camera = viewer->getCamera();
 
-    bool skyblend = _skyblend->getBoolValue();
-    if ( skyblend ) {
-       
-        if ( _textures->getBoolValue() ) {
-            SGVec4f clearColor(l->adj_fog_color());
-            camera->setClearColor(toOsg(clearColor));
-        }
-    } else {
-        SGVec4f clearColor(l->sky_color());
-        camera->setClearColor(toOsg(clearColor));
-    }
-
-    // update fog params if visibility has changed
-    double visibility_meters = _visibility_m->getDoubleValue();
-    _sky->set_visibility(visibility_meters);
-
-    double altitude_m = _altitude_ft->getDoubleValue() * SG_FEET_TO_METER;
-    _sky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
-
-    // update the sky dome
-    if ( skyblend ) {
-
-        // The sun and moon distances are scaled down versions
-        // of the actual distance to get both the moon and the sun
-        // within the range of the far clip plane.
-        // Moon distance:    384,467 kilometers
-        // Sun distance: 150,000,000 kilometers
-
-        double sun_horiz_eff, moon_horiz_eff;
-        if (_horizon_effect->getBoolValue()) {
-            sun_horiz_eff
-                = 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_sun_angle()),
-                                             0.0),
-                             0.33) / 3.0;
-            moon_horiz_eff
-                = 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_moon_angle()),
-                                             0.0),
-                             0.33)/3.0;
-        } else {
-           sun_horiz_eff = moon_horiz_eff = 1.0;
-        }
-
-        SGSkyState sstate;
-        sstate.pos       = current__view->getViewPosition();
-        sstate.pos_geod  = current__view->getPosition();
-        sstate.ori       = current__view->getViewOrientation();
-        sstate.spin      = l->get_sun_rotation();
-        sstate.gst       = globals->get_time_params()->getGst();
-        sstate.sun_dist  = 50000.0 * sun_horiz_eff;
-        sstate.moon_dist = 40000.0 * moon_horiz_eff;
-        sstate.sun_angle = l->get_sun_angle();
-
-        SGSkyColor scolor;
-        scolor.sky_color   = SGVec3f(l->sky_color().data());
-        scolor.adj_sky_color = SGVec3f(l->adj_sky_color().data());
-        scolor.fog_color   = SGVec3f(l->adj_fog_color().data());
-        scolor.cloud_color = SGVec3f(l->cloud_color().data());
-        scolor.sun_angle   = l->get_sun_angle();
-        scolor.moon_angle  = l->get_moon_angle();
-  
-        double delta_time_sec = _sim_delta_sec->getDoubleValue();
-        _sky->reposition( sstate, *globals->get_ephem(), delta_time_sec );
-        _sky->repaint( scolor, *globals->get_ephem() );
-
-            //OSGFIXME
-//         shadows->setupShadows(
-//           current__view->getLongitude_deg(),
-//           current__view->getLatitude_deg(),
-//           globals->get_time_params()->getGst(),
-//           globals->get_ephem()->getSunRightAscension(),
-//           globals->get_ephem()->getSunDeclination(),
-//           l->get_sun_angle());
-
-    }
-
-//     sgEnviro.setLight(l->adj_fog_color());
-//     sgEnviro.startOfFrame(current__view->get_view_pos(), 
-//         current__view->get_world_up(),
-//         current__view->getLongitude_deg(),
-//         current__view->getLatitude_deg(),
-//         current__view->getAltitudeASL_ft() * SG_FEET_TO_METER,
-//         delta_time_sec);
-
-    // OSGFIXME
-//     sgEnviro.drawLightning();
-
-//        double current_view_origin_airspeed_horiz_kt =
-//         fgGetDouble("/velocities/airspeed-kt", 0.0)
-//                        * cos( fgGetDouble("/orientation/pitch-deg", 0.0)
-//                                * SGD_DEGREES_TO_RADIANS);
-
-    // OSGFIXME
-//     if( is_internal )
-//         shadows->endOfFrame();
+    SGVec4f clearColor(l->adj_fog_color());
+    camera->setClearColor(toOsg(clearColor));
 
+    updateSky();
+    
     // need to call the update visitor once
-    mFrameStamp->setCalendarTime(*globals->get_time_params()->getGmt());
-    mUpdateVisitor->setViewData(current__view->getViewPosition(),
+    _frameStamp->setCalendarTime(*globals->get_time_params()->getGmt());
+    _updateVisitor->setViewData(current__view->getViewPosition(),
                                 current__view->getViewOrientation());
     SGVec3f direction(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2]);
-    mUpdateVisitor->setLight(direction, l->scene_ambient(),
+    _updateVisitor->setLight(direction, l->scene_ambient(),
                              l->scene_diffuse(), l->scene_specular(),
                              l->adj_fog_color(),
                              l->get_sun_angle()*SGD_RADIANS_TO_DEGREES);
-    mUpdateVisitor->setVisibility(actual_visibility);
-    simgear::GroundLightManager::instance()->update(mUpdateVisitor.get());
+    _updateVisitor->setVisibility(actual_visibility);
+    simgear::GroundLightManager::instance()->update(_updateVisitor.get());
     osg::Node::NodeMask cullMask = ~simgear::LIGHTS_BITS & ~simgear::PICK_BIT;
     cullMask |= simgear::GroundLightManager::instance()
-        ->getLightNodeMask(mUpdateVisitor.get());
+        ->getLightNodeMask(_updateVisitor.get());
     if (_panel_hotspots->getBoolValue())
         cullMask |= simgear::PICK_BIT;
     CameraGroup::getDefault()->setCameraCullMasks(cullMask);
        if ( !_classicalRenderer ) {
                _fogColor->set( toOsg( l->adj_fog_color() ) );
-               _fogDensity->set( float( mUpdateVisitor->getFogExp2Density() ) );
+               _fogDensity->set( float( _updateVisitor->getFogExp2Density() ) );
        }
 }
 
+void
+FGRenderer::updateSky()
+{
+    // update fog params if visibility has changed
+    double visibility_meters = _visibility_m->getDoubleValue();
+    _sky->set_visibility(visibility_meters);
+    
+    double altitude_m = _altitude_ft->getDoubleValue() * SG_FEET_TO_METER;
+    _sky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
+
+    FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
+    
+    // The sun and moon distances are scaled down versions
+    // of the actual distance to get both the moon and the sun
+    // within the range of the far clip plane.
+    // Moon distance:    384,467 kilometers
+    // Sun distance: 150,000,000 kilometers
+    
+    double sun_horiz_eff, moon_horiz_eff;
+    if (_horizon_effect->getBoolValue()) {
+        sun_horiz_eff
+        = 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_sun_angle()),
+                                     0.0),
+                     0.33) / 3.0;
+        moon_horiz_eff
+        = 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_moon_angle()),
+                                     0.0),
+                     0.33)/3.0;
+    } else {
+        sun_horiz_eff = moon_horiz_eff = 1.0;
+    }
+    
+    SGSkyState sstate;
+    sstate.pos       = globals->get_current_view()->getViewPosition();
+    sstate.pos_geod  = globals->get_current_view()->getPosition();
+    sstate.ori       = globals->get_current_view()->getViewOrientation();
+    sstate.spin      = l->get_sun_rotation();
+    sstate.gst       = globals->get_time_params()->getGst();
+    sstate.sun_dist  = 50000.0 * sun_horiz_eff;
+    sstate.moon_dist = 40000.0 * moon_horiz_eff;
+    sstate.sun_angle = l->get_sun_angle();
+    
+    SGSkyColor scolor;
+    scolor.sky_color   = SGVec3f(l->sky_color().data());
+    scolor.adj_sky_color = SGVec3f(l->adj_sky_color().data());
+    scolor.fog_color   = SGVec3f(l->adj_fog_color().data());
+    scolor.cloud_color = SGVec3f(l->cloud_color().data());
+    scolor.sun_angle   = l->get_sun_angle();
+    scolor.moon_angle  = l->get_moon_angle();
+    
+    double delta_time_sec = _sim_delta_sec->getDoubleValue();
+    _sky->reposition( sstate, *globals->get_ephem(), delta_time_sec );
+    _sky->repaint( scolor, *globals->get_ephem() );
+}
+                                    
 void
 FGRenderer::resize( int width, int height )
 {
@@ -1849,13 +1826,13 @@ FGRenderer::setEventHandler(FGEventHandler* eventHandler_)
 void
 FGRenderer::addCamera(osg::Camera* camera, bool useSceneData)
 {
-    mRealRoot->addChild(camera);
+    _viewerSceneRoot->addChild(camera);
 }
 
 void
 FGRenderer::removeCamera(osg::Camera* camera)
 {
-    mRealRoot->removeChild(camera);
+    _viewerSceneRoot->removeChild(camera);
 }
                                     
 void
@@ -1867,7 +1844,8 @@ FGRenderer::setPlanes( double zNear, double zFar )
 bool
 fgDumpSceneGraphToFile(const char* filename)
 {
-    return osgDB::writeNodeFile(*mRealRoot.get(), filename);
+    osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
+    return osgDB::writeNodeFile(*viewer->getSceneData(), filename);
 }
 
 bool