]> git.mxchange.org Git - flightgear.git/commitdiff
Modified Files:
authorfrohlich <frohlich>
Thu, 3 May 2007 18:12:29 +0000 (18:12 +0000)
committerfrohlich <frohlich>
Thu, 3 May 2007 18:12:29 +0000 (18:12 +0000)
src/GUI/new_gui.cxx src/GUI/new_gui.hxx src/Main/main.cxx
  src/Main/renderer.cxx src/Main/renderer.hxx
src/Main/splash.cxx src/Main/splash.hxx
src/Scenery/scenery.hxx: Move splash screen into the scenegraph.

src/GUI/new_gui.cxx
src/GUI/new_gui.hxx
src/Main/main.cxx
src/Main/renderer.cxx
src/Main/renderer.hxx
src/Main/splash.cxx
src/Main/splash.hxx
src/Scenery/scenery.hxx

index fb36cc0ca053fd7abea807ae7c9f9a5f258b5bb3..fa1abaf5353003824d339829b9de0a8facc2441f 100644 (file)
@@ -423,27 +423,11 @@ FGFontCache::~FGFontCache()
 struct FGFontCache::fnt *
 FGFontCache::getfnt(const char *name, float size, float slant)
 {
-    if (!_initialized) {
-        char *envp = ::getenv("FG_FONTS");
-        if (envp != NULL) {
-            _path.set(envp);
-        } else {
-            _path.set(globals->get_fg_root());
-            _path.append("Fonts");
-        }
-
-        for (int i = 0; guifonts[i].name; i++)
-            _fonts[guifonts[i].name] = new fnt(guifonts[i].font);
-
-        _initialized = true;
-    }
-
     _itt_t it;
     if ((it = _fonts.find(name)) != _fonts.end())
         return it->second;
 
-    SGPath path(_path);
-    path.append(name);
+    SGPath path = getfntpath(name);
 
     fnt *f = new fnt();
     f->texfont = new fntTexFont;
@@ -483,4 +467,35 @@ FGFontCache::get(SGPropertyNode *node)
     return get(name, size, slant);
 }
 
+SGPath
+FGFontCache::getfntpath(const char *name)
+{
+    if (!_initialized) {
+        char *envp = ::getenv("FG_FONTS");
+        if (envp != NULL) {
+            _path.set(envp);
+        } else {
+            _path.set(globals->get_fg_root());
+            _path.append("Fonts");
+        }
+
+        for (int i = 0; guifonts[i].name; i++)
+            _fonts[guifonts[i].name] = new fnt(guifonts[i].font);
+
+        _initialized = true;
+    }
+
+    SGPath path(_path);
+    if (name && std::string(name) != "") {
+        path.append(name);
+        if (path.exists())
+            return path;
+    }
+
+    path = SGPath(_path);
+    path.append("Helvetica.txf");
+    
+    return path;
+}
+
 // end of new_gui.cxx
index d258399f60ef760f535d48f71ead9b4c09f36fc8..981628af8406eb0843bb162eb0532ee7d0e13bae 100644 (file)
@@ -315,6 +315,8 @@ public:
     puFont *get(SGPropertyNode *node);
 
     fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0);
+
+    SGPath getfntpath(const char *name);
 };
 
 
index b47080c304b00b9193f37ee0f48c12ade6d2563f..2cd9514e04d246a8b99d5b55cc6c537066c61e9e 100644 (file)
@@ -977,9 +977,6 @@ bool fgMainInit( int argc, char **argv ) {
         exit(-1);
     }
 
-    //OSGFIXME
-//     sgUseDisplayList = fgGetBool( "/sim/rendering/use-display-list", true );
-
     // Load the configuration parameters.  (Command line options
     // override config file options.  Config file options override
     // defaults.)
@@ -1021,7 +1018,7 @@ bool fgMainInit( int argc, char **argv ) {
 
     // Initialize the splash screen right away
     fntInit();
-    fgSplashInit(fgGetString("/sim/startup/splash-texture"));
+    fgSplashInit();
 
     // pass control off to the master event handler
     fgOSMainLoop();
index f6522af0a97f97a2448b1e2c076e2c8878ec9fdf..ee0ee17438abf5c914567d78d2077cabf267b150 100644 (file)
@@ -143,20 +143,6 @@ public:
     glPopClientAttrib();
     glPopAttrib();
 
-    // Fade out the splash screen over the first three seconds.
-    double t = globals->get_sim_time_sec();
-    if (t <= 2.5) {
-      glPushAttrib(GL_ALL_ATTRIB_BITS);
-      glPushClientAttrib(~0u);
-
-      fgSplashUpdate((2.5 - t) / 2.5);
-
-      glPopClientAttrib();
-      glPopAttrib();
-    } else {
-      fgSplashExit();
-    }
-
     state.popStateSet();
     state.dirtyAllModes();
     state.dirtyAllAttributes();
@@ -326,6 +312,23 @@ private:
   SGSharedPtr<SGPropertyNode> mFogEnabled;
 };
 
+// update callback for the switch node guarding that splash
+class FGScenerySwitchCallback : public osg::NodeCallback {
+public:
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+  {
+    assert(dynamic_cast<osg::Switch*>(node));
+    osg::Switch* sw = static_cast<osg::Switch*>(node);
+
+    double t = globals->get_sim_time_sec();
+    bool enabled = 0 < t;
+    sw->setValue(0, enabled);
+    if (!enabled)
+      return;
+    traverse(node, nv);
+  }
+};
+
 // fog constants.  I'm a little nervous about putting actual code out
 // here but it seems to work (?)
 static const double m_log01 = -log( 0.01 );
@@ -343,6 +346,8 @@ osg::ref_ptr<osgUtil::SceneView> sceneView = new osgUtil::SceneView;  // This Sc
 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> mRoot = new osg::Group;
 
 static osg::ref_ptr<osg::CameraView> mCameraView = new osg::CameraView;
@@ -368,6 +373,17 @@ FGRenderer::~FGRenderer()
 }
 
 // Initialize various GL/view parameters
+void
+FGRenderer::splashinit( void ) {
+   // Add the splash screen node
+   mRealRoot->addChild(fgCreateSplashNode());
+   sceneView->setSceneData(mRealRoot.get());
+
+   sceneView->setDefaults(osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT);
+   sceneView->setFrameStamp(mFrameStamp.get());
+   sceneView->setUpdateVisitor(mUpdateVisitor.get());
+}
+
 void
 FGRenderer::init( void ) {
 
@@ -395,18 +411,11 @@ FGRenderer::init( void ) {
     glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
     glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
 
-    sceneView->setDefaults(osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT);
-
     mFog->setMode(osg::Fog::EXP2);
     mRunwayLightingFog->setMode(osg::Fog::EXP2);
     mTaxiLightingFog->setMode(osg::Fog::EXP2);
     mGroundLightingFog->setMode(osg::Fog::EXP2);
 
-    sceneView->setFrameStamp(mFrameStamp.get());
-
-    mUpdateVisitor = new SGUpdateVisitor;
-    sceneView->setUpdateVisitor(mUpdateVisitor.get());
-
     sceneView->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
     sceneView->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
 
@@ -505,7 +514,6 @@ FGRenderer::init( void ) {
     guiCamera->setInheritanceMask(inheritanceMask);
     guiCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
     guiCamera->setCullingMode(osg::CullSettings::NO_CULLING);
-    mRoot->addChild(guiCamera);
     osg::Geode* geode = new osg::Geode;
     geode->addDrawable(new SGPuDrawable);
     geode->addDrawable(new SGHUDAndPanelDrawable);
@@ -534,9 +542,13 @@ FGRenderer::init( void ) {
     stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
 
     mCameraView->addChild(mRoot.get());
-    sceneView->setSceneData(mCameraView.get());
 
-//  sceneView->getState()->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
+    osg::Switch* sw = new osg::Switch;
+    sw->setUpdateCallback(new FGScenerySwitchCallback);
+    sw->addChild(mCameraView.get());
+
+    mRealRoot->addChild(sw);
+    mRealRoot->addChild(guiCamera);
 }
 
 
@@ -547,25 +559,23 @@ FGRenderer::update( bool refresh_camera_settings ) {
                           || fgGetBool("sim/sceneryloaded-override");
 
     if ( idle_state < 1000 || !scenery_loaded ) {
-        if (sceneView.valid() && sceneView->getState()) {
-            sceneView->getState()->setActiveTextureUnit(0);
-            sceneView->getState()->setClientActiveTextureUnit(0);
-            sceneView->getState()->disableAllVertexArrays();
-        }
-        // still initializing, draw the splash screen
-        glPushAttrib(GL_ALL_ATTRIB_BITS);
-        glPushClientAttrib(~0u);
-
-        fgSplashUpdate(1.0);
-
-        glPopClientAttrib();
-        glPopAttrib();
+        fgSetDouble("/sim/startup/splash-alpha", 1.0);
 
         // Keep resetting sim time while the sim is initializing
         globals->set_sim_time_sec( 0.0 );
+
+        // the splash screen is now in the scenegraph
+        sceneView->update();
+        sceneView->cull();
+        sceneView->draw();
+
         return;
     }
 
+    // Fade out the splash screen over the first three seconds.
+    double sAlpha = SGMiscd::max(0, (2.5 - globals->get_sim_time_sec()) / 2.5);
+    fgSetDouble("/sim/startup/splash-alpha", sAlpha);
+
     bool skyblend = fgGetBool("/sim/rendering/skyblend");
     bool use_point_sprites = fgGetBool("/sim/rendering/point-sprites");
     bool enhanced_lighting = fgGetBool("/sim/rendering/enhanced-lighting");
index b80087da6b8e1ff8fd0b1c6b11050227447a14ec..02e0f6982ddea882ac6762bf84693d1ed90b653b 100644 (file)
@@ -24,6 +24,7 @@ public:
     FGRenderer();
     ~FGRenderer();
 
+    void splashinit();
     void init();
 
     static void resize(int width, int height );
index 761c14e5b74e9038a2381416ab126d51ba2d8127..f922ce448f3bdb2dd81a1f8ae69295f1f29d210c 100644 (file)
 #  include <config.h>
 #endif
 
-#ifdef SG_MATH_EXCEPTION_CLASH
-#  include <math.h>
-#endif
-
-#ifdef HAVE_WINDOWS_H
-#  include <windows.h>
-#endif
-
-#include <string.h>
+#include <osg/BlendFunc>
+#include <osg/Camera>
+#include <osg/Depth>
+#include <osg/Geometry>
+#include <osg/Node>
+#include <osg/NodeCallback>
+#include <osg/NodeVisitor>
+#include <osg/StateSet>
+#include <osg/Switch>
+#include <osg/Texture2D>
+#include <osgUtil/CullVisitor>
+#include <osgText/Text>
+#include <osgDB/ReadFile>
 
-#include <plib/pu.h>
 #include <simgear/compiler.h>
 
-#include SG_GLU_H
-
 #include <simgear/debug/logstream.hxx>
-#include <simgear/screen/texture.hxx>
 #include <simgear/math/sg_random.h>
 #include <simgear/misc/sg_path.hxx>
 
 #include "globals.hxx"
 #include "fg_props.hxx"
 #include "splash.hxx"
-#include "fg_os.hxx"
 #include "renderer.hxx"
+#include "fg_os.hxx"
 
-static const char *progress_text = 0;
-static SGTexture *splash = new SGTexture;
-SGPropertyNode_ptr style = 0;
-
-
-// Initialize the splash screen
-void fgSplashInit ( const char *splash_texture ) {
-    fgRequestRedraw();
-
-    SG_LOG( SG_GENERAL, SG_INFO, "Initializing splash screen" );
-
-    style = fgGetNode("/sim/gui/style[0]", true);
-
-    if (!fgGetBool("/sim/startup/splash-screen"))
-        return;
-
-    splash->bind();
-
-    SGPath tpath( globals->get_fg_root() );
-    if (splash_texture == NULL || !strcmp(splash_texture, "")) {
-        // load in the texture data
-        int num = (int)(sg_random() * 5.0 + 1.0);
-        char num_str[5];
-        snprintf(num_str, 4, "%d", num);
-
-        tpath.append( "Textures/Splash" );
-        tpath.concat( num_str );
-        tpath.concat( ".rgb" );
-    } else
-        tpath.append( splash_texture );
-
-    splash->read_rgba_texture(tpath.c_str());
-    if (!splash->usable())
-    {
-        // Try compressed
-        SGPath fg_tpath = tpath;
-        fg_tpath.concat( ".gz" );
-
-        splash->read_rgba_texture(fg_tpath.c_str());
-        if ( !splash->usable() )
-        {
-            SG_LOG( SG_GENERAL, SG_ALERT,
-                    "Error in loading splash screen texture " << tpath.str() );
-            exit(-1);
-        }
+class FGSplashUpdateCallback : public osg::Drawable::UpdateCallback {
+public:
+  FGSplashUpdateCallback(osg::Vec4Array* colorArray, SGPropertyNode* prop) :
+    _colorArray(colorArray),
+    _colorProperty(prop),
+    _alphaProperty(fgGetNode("/sim/startup/splash-alpha", true))
+  { }
+  virtual void update(osg::NodeVisitor*, osg::Drawable*)
+  {
+    FGColor c(0, 0, 0);
+    if (_colorProperty) {
+      c.merge(_colorProperty);
+      (*_colorArray)[0][0] = c.red();
+      (*_colorArray)[0][1] = c.green();
+      (*_colorArray)[0][2] = c.blue();
+    }
+    (*_colorArray)[0][3] = _alphaProperty->getFloatValue();
+    _colorArray->dirty();
+  }
+private:
+  osg::ref_ptr<osg::Vec4Array> _colorArray;
+  SGSharedPtr<const SGPropertyNode> _colorProperty;
+  SGSharedPtr<const SGPropertyNode> _alphaProperty;
+};
+
+class FGSplashTextUpdateCallback : public osg::Drawable::UpdateCallback {
+public:
+  FGSplashTextUpdateCallback(const SGPropertyNode* prop) :
+    _textProperty(prop),
+    _alphaProperty(fgGetNode("/sim/startup/splash-alpha", true)),
+    _styleProperty(fgGetNode("/sim/gui/style[0]", true))
+  {}
+  virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)
+  {
+    assert(dynamic_cast<osgText::Text*>(drawable));
+    osgText::Text* text = static_cast<osgText::Text*>(drawable);
+
+    FGColor c(1.0, 0.9, 0.0);
+    c.merge(_styleProperty->getNode("colors/splash-font"));
+    float alpha = _alphaProperty->getFloatValue();
+    text->setColor(osg::Vec4(c.red(), c.green(), c.blue(), alpha));
+
+    const char* s = _textProperty->getStringValue();
+    if (s && fgGetBool("/sim/startup/splash-progress", true))
+      text->setText(s);
+    else
+      text->setText("");
+  }
+private:
+  SGSharedPtr<const SGPropertyNode> _textProperty;
+  SGSharedPtr<const SGPropertyNode> _alphaProperty;
+  SGSharedPtr<const SGPropertyNode> _styleProperty;
+};
+
+
+class FGSplashContentProjectionCalback : public osg::NodeCallback {
+public:
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+  { 
+    assert(dynamic_cast<osgUtil::CullVisitor*>(nv));
+    osgUtil::CullVisitor* cullVisitor = static_cast<osgUtil::CullVisitor*>(nv);
+
+    // adjust the projection matrix in a way that preserves the aspect ratio
+    // of the content ...
+    const osg::Viewport* viewport = cullVisitor->getViewport();
+    float viewportAspect = float(viewport->height())/float(viewport->width());
+
+    float height, width;
+    if (viewportAspect < 1) {
+      height = 1;
+      width = 1/viewportAspect;
+    } else {
+      height = viewportAspect;
+      width = 1;
     }
 
-    splash->select();
-}
+    osg::RefMatrix* matrix = new osg::RefMatrix;
+    matrix->makeOrtho2D(-width, width, -height, height);
 
+    // The trick is to have the projection matrix adapted independent
+    // of the scenegraph but dependent on the viewport of this current
+    // camera we cull for. Therefore we do not put that projection matrix into
+    // an additional camera rather than from within that cull callback.
+    cullVisitor->pushProjectionMatrix(matrix);
+    traverse(node, nv);
+    cullVisitor->popProjectionMatrix();
+  }
+};
 
-void fgSplashExit ()
+static osg::Node* fgCreateSplashCamera()
 {
-    delete splash;
-    splash = 0;
+  const char* splash_texture = fgGetString("/sim/startup/splash-texture");
+  SGSharedPtr<SGPropertyNode> style = fgGetNode("/sim/gui/style[0]", true);
+
+  SGPath tpath( globals->get_fg_root() );
+  if (splash_texture == NULL || !strcmp(splash_texture, "")) {
+    // load in the texture data
+    int num = (int)(sg_random() * 5.0 + 1.0);
+    char num_str[5];
+    snprintf(num_str, 4, "%d", num);
+
+    tpath.append( "Textures/Splash" );
+    tpath.concat( num_str );
+    tpath.concat( ".rgb" );
+  } else
+    tpath.append( splash_texture );
+
+  osg::Texture2D* splashTexture = new osg::Texture2D;
+  splashTexture->setImage(osgDB::readImageFile(tpath.c_str()));
+
+  osg::Camera* camera = new osg::Camera;
+  camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+  camera->setProjectionMatrix(osg::Matrix::ortho2D(-1, 1, -1, 1));
+  camera->setViewMatrix(osg::Matrix::identity());
+  camera->setRenderOrder(osg::Camera::POST_RENDER, 10000);
+  camera->setClearMask(0);
+  camera->setAllowEventFocus(false);
+  camera->setCullingActive(false);
+
+  osg::StateSet* stateSet = camera->getOrCreateStateSet();
+  stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
+  stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
+  stateSet->setAttribute(new osg::BlendFunc);
+  stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
+  stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+  stateSet->setAttribute(new osg::Depth(osg::Depth::ALWAYS, 0, 1, false));
+  stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+
+
+  osg::Geometry* geometry = new osg::Geometry;
+  geometry->setSupportsDisplayList(false);
+
+  osg::Vec3Array* vertexArray = new osg::Vec3Array;
+  vertexArray->push_back(osg::Vec3(-1, -1, 0));
+  vertexArray->push_back(osg::Vec3( 1, -1, 0));
+  vertexArray->push_back(osg::Vec3( 1,  1, 0));
+  vertexArray->push_back(osg::Vec3(-1,  1, 0));
+  geometry->setVertexArray(vertexArray);
+  osg::Vec4Array* colorArray = new osg::Vec4Array;
+  colorArray->push_back(osg::Vec4(0, 0, 0, 1));
+  geometry->setColorArray(colorArray);
+  geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+  geometry->addPrimitiveSet(new osg::DrawArrays(GL_POLYGON, 0, 4));
+  geometry->setUpdateCallback(new FGSplashUpdateCallback(colorArray,
+                              style->getNode("colors/splash-screen")));
+
+  osg::Geode* geode = new osg::Geode;
+  geode->addDrawable(geometry);
+
+  stateSet = geode->getOrCreateStateSet();
+  stateSet->setRenderBinDetails(1, "RenderBin");
+  camera->addChild(geode);
+
+
+  // The group is needed because of osg is handling the cull callbacks in a
+  // different way for groups than for a geode. It does not hurt here ...
+  osg::Group* group = new osg::Group;
+  group->setCullCallback(new FGSplashContentProjectionCalback);
+  camera->addChild(group);
+
+  geode = new osg::Geode;
+  stateSet = geode->getOrCreateStateSet();
+  stateSet->setRenderBinDetails(2, "RenderBin");
+  group->addChild(geode);
+
+
+  geometry = new osg::Geometry;
+  geometry->setSupportsDisplayList(false);
+
+  vertexArray = new osg::Vec3Array;
+  vertexArray->push_back(osg::Vec3(-0.84, -0.84, 0));
+  vertexArray->push_back(osg::Vec3( 0.84, -0.84, 0));
+  vertexArray->push_back(osg::Vec3( 0.84,  0.84, 0));
+  vertexArray->push_back(osg::Vec3(-0.84,  0.84, 0));
+  geometry->setVertexArray(vertexArray);
+  osg::Vec2Array* texCoordArray = new osg::Vec2Array;
+  texCoordArray->push_back(osg::Vec2(0, 0));
+  texCoordArray->push_back(osg::Vec2(1, 0));
+  texCoordArray->push_back(osg::Vec2(1, 1));
+  texCoordArray->push_back(osg::Vec2(0, 1));
+  geometry->setTexCoordArray(0, texCoordArray);
+  colorArray = new osg::Vec4Array;
+  colorArray->push_back(osg::Vec4(1, 1, 1, 1));
+  geometry->setColorArray(colorArray);
+  geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+  geometry->addPrimitiveSet(new osg::DrawArrays(GL_POLYGON, 0, 4));
+  geometry->setUpdateCallback(new FGSplashUpdateCallback(colorArray, 0));
+  stateSet = geometry->getOrCreateStateSet();
+  stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
+  stateSet->setTextureAttribute(0, splashTexture);
+  geode->addDrawable(geometry);
+
+
+  osgText::Text* text = new osgText::Text;
+  std::string fn = style->getStringValue("fonts/splash", "");
+  text->setFont(globals->get_fontcache()->getfntpath(fn.c_str()).str());
+  text->setCharacterSize(0.06);
+  text->setColor(osg::Vec4(1, 1, 1, 1));
+  text->setPosition(osg::Vec3(0, -0.92, 0));
+  text->setAlignment(osgText::Text::CENTER_CENTER);
+  SGPropertyNode* prop = fgGetNode("/sim/startup/splash-progress-text", true);
+  text->setUpdateCallback(new FGSplashTextUpdateCallback(prop));
+  geode->addDrawable(text);
+
+  text = new osgText::Text;
+  text->setFont(globals->get_fontcache()->getfntpath(fn.c_str()).str());
+  text->setCharacterSize(0.06);
+  text->setColor(osg::Vec4(1, 1, 1, 1));
+  text->setPosition(osg::Vec3(0, 0.92, 0));
+  text->setAlignment(osgText::Text::CENTER_CENTER);
+  prop = fgGetNode("/sim/startup/splash-title", true);
+  text->setUpdateCallback(new FGSplashTextUpdateCallback(prop));
+  geode->addDrawable(text);
+
+  return camera;
 }
 
-
-void fgSplashProgress ( const char *s )
-{
-    progress_text = s;
-    fgRequestRedraw();
+// update callback for the switch node guarding that splash
+class FGSplashGroupUpdateCallback : public osg::NodeCallback {
+public:
+  FGSplashGroupUpdateCallback() :
+    _splashAlphaNode(fgGetNode("/sim/startup/splash-alpha", true))
+  { }
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+  {
+    assert(dynamic_cast<osg::Group*>(node));
+    osg::Group* group = static_cast<osg::Group*>(node);
+
+    double alpha = _splashAlphaNode->getDoubleValue();
+    if (alpha <= 0 || !fgGetBool("/sim/startup/splash-screen"))
+      group->removeChild(0, group->getNumChildren());
+    else if (group->getNumChildren() == 0)
+      group->addChild(fgCreateSplashCamera());
+
+    traverse(node, nv);
+  }
+private:
+  SGSharedPtr<const SGPropertyNode> _splashAlphaNode;
+};
+
+osg::Node* fgCreateSplashNode() {
+  osg::Group* group = new osg::Group;
+  group->setUpdateCallback(new FGSplashGroupUpdateCallback);
+  return group;
 }
 
-
-// Update the splash screen with alpha specified from 0.0 to 1.0
-void fgSplashUpdate ( float alpha ) {
-    const int EMPTYSPACE = 80;
-
-    int screen_width = fgGetInt("/sim/startup/xsize", 0);
-    int screen_height = fgGetInt("/sim/startup/ysize", 0);
-
-    if (!screen_width || !screen_height)
-        return;
-
-    globals->get_renderer()->resize(screen_width, screen_height);
-    int size = screen_width < (screen_height - EMPTYSPACE)
-            ? screen_width : screen_height - EMPTYSPACE;
-    if (size > 512)
-        size = 512;
-
-    int xmin, ymin, xmax, ymax;
-    xmin = (screen_width - size) / 2;
-    xmax = xmin + size;
-
-    ymin = (screen_height - size) / 2;
-    ymax = ymin + size;
-
-    glMatrixMode(GL_PROJECTION);
-    glPushMatrix();
-    glLoadIdentity();
-    gluOrtho2D(0, screen_width, 0, screen_height);
-    glViewport(0, 0, screen_width, screen_height);
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadIdentity();
-
-    glDisable(GL_DEPTH_TEST);
-    glDisable(GL_LIGHTING);
-    glDisable(GL_CULL_FACE);
-
-    // draw the background
-    FGColor c(0.0, 0.0, 0.0);
-    c.merge(style->getNode("colors/splash-screen"));
-    glColor4f(c.red(), c.green(), c.blue(), alpha );
-    glBegin(GL_POLYGON);
-    glVertex2f(0.0, 0.0);
-    glVertex2f(screen_width, 0.0);
-    glVertex2f(screen_width, screen_height);
-    glVertex2f(0.0, screen_height);
-    glEnd();
-
-    glEnable(GL_ALPHA_TEST);
-    glEnable(GL_BLEND);
-    glAlphaFunc(GL_GREATER, 0.1f);
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-    // now draw the logo
-    if (fgGetBool("/sim/startup/splash-screen", true)) {
-        glEnable(GL_TEXTURE_2D);
-        splash->bind();
-        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
-        glColor4f( 1.0, 1.0, 1.0, alpha );
-        glBegin(GL_POLYGON);
-        glTexCoord2f(0.0, 0.0); glVertex2f(xmin, ymin);
-        glTexCoord2f(1.0, 0.0); glVertex2f(xmax, ymin);
-        glTexCoord2f(1.0, 1.0); glVertex2f(xmax, ymax);
-        glTexCoord2f(0.0, 1.0); glVertex2f(xmin, ymax);
-        glEnd();
-        glDisable(GL_TEXTURE_2D);
-    }
-
-    if (progress_text && fgGetBool("/sim/startup/splash-progress", true)) {
-        puFont *fnt = globals->get_fontcache()->get(style->getNode("fonts/splash"));
-
-        FGColor c(1.0, 0.9, 0.0);
-        c.merge(style->getNode("colors/splash-font"));
-        glColor4f(c.red(), c.green(), c.blue(), alpha);
-
-        float height = fnt->getStringHeight("/M$");
-        float descender = fnt->getStringDescender();
-        float width = fnt->getFloatStringWidth(progress_text);
-        fnt->drawString(progress_text, int((screen_width - width) / 2), int(10 + descender));
-
-        const char *title = fgGetString("/sim/startup/splash-title", "");
-        width = fnt->getFloatStringWidth(title);
-        fnt->drawString(title, int((screen_width - width) / 2), int(screen_height - 10 - height));
-    }
-
-    glEnable(GL_DEPTH_TEST);
-    glEnable(GL_LIGHTING);
-
-    glMatrixMode(GL_PROJECTION);
-    glPopMatrix();
-    glMatrixMode(GL_MODELVIEW);
-    glPopMatrix();
+// Initialize the splash screen
+void fgSplashInit () {
+  SG_LOG( SG_GENERAL, SG_INFO, "Initializing splash screen" );
+  globals->get_renderer()->splashinit();
+  fgRequestRedraw();
 }
 
-
+void fgSplashProgress ( const char *text ) {
+  SG_LOG( SG_GENERAL, SG_INFO, "Splash screen progress " << text );
+  fgSetString("/sim/startup/splash-progress-text", text);
+  fgRequestRedraw();
+}
index 7ee57e856f7ab300099dad7b814639c3a0aa8dfb..30643c2abf80d78e2aec7aa7c0324c5e1e0591ec 100644 (file)
 #ifndef _SPLASH_HXX
 #define _SPLASH_HXX
 
+#include <osg/Node>
 
 #ifndef __cplusplus
 # error This library requires C++
 #endif
 
-
 // Initialize the splash screen
-void fgSplashInit ( const char *splash_texture );
-
-// Update the splash screen with alpha specified from 0.0 to 1.0
-void fgSplashUpdate ( float alpha );
+void fgSplashInit ();
 
 // Set progress information
 void fgSplashProgress ( const char *text );
 
-// Free texture memory
-void fgSplashExit ();
-
+// Retrieve the splash screen node ...
+osg::Node* fgCreateSplashNode();
 
 #endif // _SPLASH_HXX
 
index 4229e4c583fdcfe99094285051b31702d801a701..9ee3ae482acc88838db9b8378f27d4021e12e6b7 100644 (file)
@@ -54,7 +54,7 @@ class FGScenery : public SGSubsystem {
     // angle of sun relative to current local horizontal
     double sun_angle;
 
-    // SSG scene graph
+    // scene graph
     osg::ref_ptr<osg::Group> scene_graph;
     osg::ref_ptr<osg::Group> terrain_branch;
     osg::ref_ptr<osg::Group> gnd_lights_root;