Modified Files:
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.
This commit is contained in:
parent
9438288755
commit
2f8beb56ea
8 changed files with 354 additions and 235 deletions
|
@ -423,27 +423,11 @@ FGFontCache::~FGFontCache()
|
||||||
struct FGFontCache::fnt *
|
struct FGFontCache::fnt *
|
||||||
FGFontCache::getfnt(const char *name, float size, float slant)
|
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;
|
_itt_t it;
|
||||||
if ((it = _fonts.find(name)) != _fonts.end())
|
if ((it = _fonts.find(name)) != _fonts.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
|
|
||||||
SGPath path(_path);
|
SGPath path = getfntpath(name);
|
||||||
path.append(name);
|
|
||||||
|
|
||||||
fnt *f = new fnt();
|
fnt *f = new fnt();
|
||||||
f->texfont = new fntTexFont;
|
f->texfont = new fntTexFont;
|
||||||
|
@ -483,4 +467,35 @@ FGFontCache::get(SGPropertyNode *node)
|
||||||
return get(name, size, slant);
|
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
|
// end of new_gui.cxx
|
||||||
|
|
|
@ -315,6 +315,8 @@ public:
|
||||||
puFont *get(SGPropertyNode *node);
|
puFont *get(SGPropertyNode *node);
|
||||||
|
|
||||||
fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0);
|
fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0);
|
||||||
|
|
||||||
|
SGPath getfntpath(const char *name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -977,9 +977,6 @@ bool fgMainInit( int argc, char **argv ) {
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//OSGFIXME
|
|
||||||
// sgUseDisplayList = fgGetBool( "/sim/rendering/use-display-list", true );
|
|
||||||
|
|
||||||
// Load the configuration parameters. (Command line options
|
// Load the configuration parameters. (Command line options
|
||||||
// override config file options. Config file options override
|
// override config file options. Config file options override
|
||||||
// defaults.)
|
// defaults.)
|
||||||
|
@ -1021,7 +1018,7 @@ bool fgMainInit( int argc, char **argv ) {
|
||||||
|
|
||||||
// Initialize the splash screen right away
|
// Initialize the splash screen right away
|
||||||
fntInit();
|
fntInit();
|
||||||
fgSplashInit(fgGetString("/sim/startup/splash-texture"));
|
fgSplashInit();
|
||||||
|
|
||||||
// pass control off to the master event handler
|
// pass control off to the master event handler
|
||||||
fgOSMainLoop();
|
fgOSMainLoop();
|
||||||
|
|
|
@ -143,20 +143,6 @@ public:
|
||||||
glPopClientAttrib();
|
glPopClientAttrib();
|
||||||
glPopAttrib();
|
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.popStateSet();
|
||||||
state.dirtyAllModes();
|
state.dirtyAllModes();
|
||||||
state.dirtyAllAttributes();
|
state.dirtyAllAttributes();
|
||||||
|
@ -326,6 +312,23 @@ private:
|
||||||
SGSharedPtr<SGPropertyNode> mFogEnabled;
|
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
|
// fog constants. I'm a little nervous about putting actual code out
|
||||||
// here but it seems to work (?)
|
// here but it seems to work (?)
|
||||||
static const double m_log01 = -log( 0.01 );
|
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<osg::FrameStamp> mFrameStamp = new osg::FrameStamp;
|
||||||
static osg::ref_ptr<SGUpdateVisitor> mUpdateVisitor= new SGUpdateVisitor;
|
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::Group> mRoot = new osg::Group;
|
||||||
|
|
||||||
static osg::ref_ptr<osg::CameraView> mCameraView = new osg::CameraView;
|
static osg::ref_ptr<osg::CameraView> mCameraView = new osg::CameraView;
|
||||||
|
@ -368,6 +373,17 @@ FGRenderer::~FGRenderer()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize various GL/view parameters
|
// 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
|
void
|
||||||
FGRenderer::init( void ) {
|
FGRenderer::init( void ) {
|
||||||
|
|
||||||
|
@ -395,18 +411,11 @@ FGRenderer::init( void ) {
|
||||||
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
|
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
|
||||||
glHint(GL_POINT_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);
|
mFog->setMode(osg::Fog::EXP2);
|
||||||
mRunwayLightingFog->setMode(osg::Fog::EXP2);
|
mRunwayLightingFog->setMode(osg::Fog::EXP2);
|
||||||
mTaxiLightingFog->setMode(osg::Fog::EXP2);
|
mTaxiLightingFog->setMode(osg::Fog::EXP2);
|
||||||
mGroundLightingFog->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->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||||
sceneView->getCamera()->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->setInheritanceMask(inheritanceMask);
|
||||||
guiCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
guiCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||||
guiCamera->setCullingMode(osg::CullSettings::NO_CULLING);
|
guiCamera->setCullingMode(osg::CullSettings::NO_CULLING);
|
||||||
mRoot->addChild(guiCamera);
|
|
||||||
osg::Geode* geode = new osg::Geode;
|
osg::Geode* geode = new osg::Geode;
|
||||||
geode->addDrawable(new SGPuDrawable);
|
geode->addDrawable(new SGPuDrawable);
|
||||||
geode->addDrawable(new SGHUDAndPanelDrawable);
|
geode->addDrawable(new SGHUDAndPanelDrawable);
|
||||||
|
@ -534,9 +542,13 @@ FGRenderer::init( void ) {
|
||||||
stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
|
stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
|
||||||
|
|
||||||
mCameraView->addChild(mRoot.get());
|
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");
|
|| fgGetBool("sim/sceneryloaded-override");
|
||||||
|
|
||||||
if ( idle_state < 1000 || !scenery_loaded ) {
|
if ( idle_state < 1000 || !scenery_loaded ) {
|
||||||
if (sceneView.valid() && sceneView->getState()) {
|
fgSetDouble("/sim/startup/splash-alpha", 1.0);
|
||||||
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();
|
|
||||||
|
|
||||||
// Keep resetting sim time while the sim is initializing
|
// Keep resetting sim time while the sim is initializing
|
||||||
globals->set_sim_time_sec( 0.0 );
|
globals->set_sim_time_sec( 0.0 );
|
||||||
|
|
||||||
|
// the splash screen is now in the scenegraph
|
||||||
|
sceneView->update();
|
||||||
|
sceneView->cull();
|
||||||
|
sceneView->draw();
|
||||||
|
|
||||||
return;
|
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 skyblend = fgGetBool("/sim/rendering/skyblend");
|
||||||
bool use_point_sprites = fgGetBool("/sim/rendering/point-sprites");
|
bool use_point_sprites = fgGetBool("/sim/rendering/point-sprites");
|
||||||
bool enhanced_lighting = fgGetBool("/sim/rendering/enhanced-lighting");
|
bool enhanced_lighting = fgGetBool("/sim/rendering/enhanced-lighting");
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
FGRenderer();
|
FGRenderer();
|
||||||
~FGRenderer();
|
~FGRenderer();
|
||||||
|
|
||||||
|
void splashinit();
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
static void resize(int width, int height );
|
static void resize(int width, int height );
|
||||||
|
|
|
@ -26,23 +26,23 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SG_MATH_EXCEPTION_CLASH
|
#include <osg/BlendFunc>
|
||||||
# include <math.h>
|
#include <osg/Camera>
|
||||||
#endif
|
#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>
|
||||||
|
|
||||||
#ifdef HAVE_WINDOWS_H
|
|
||||||
# include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <plib/pu.h>
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
#include SG_GLU_H
|
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/screen/texture.hxx>
|
|
||||||
#include <simgear/math/sg_random.h>
|
#include <simgear/math/sg_random.h>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
||||||
|
@ -51,166 +51,264 @@
|
||||||
#include "globals.hxx"
|
#include "globals.hxx"
|
||||||
#include "fg_props.hxx"
|
#include "fg_props.hxx"
|
||||||
#include "splash.hxx"
|
#include "splash.hxx"
|
||||||
#include "fg_os.hxx"
|
|
||||||
#include "renderer.hxx"
|
#include "renderer.hxx"
|
||||||
|
#include "fg_os.hxx"
|
||||||
|
|
||||||
static const char *progress_text = 0;
|
class FGSplashUpdateCallback : public osg::Drawable::UpdateCallback {
|
||||||
static SGTexture *splash = new SGTexture;
|
public:
|
||||||
SGPropertyNode_ptr style = 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static osg::Node* fgCreateSplashCamera()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the splash screen
|
// Initialize the splash screen
|
||||||
void fgSplashInit ( const char *splash_texture ) {
|
void fgSplashInit () {
|
||||||
fgRequestRedraw();
|
SG_LOG( SG_GENERAL, SG_INFO, "Initializing splash screen" );
|
||||||
|
globals->get_renderer()->splashinit();
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "Initializing splash screen" );
|
fgRequestRedraw();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
splash->select();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fgSplashProgress ( const char *text ) {
|
||||||
void fgSplashExit ()
|
SG_LOG( SG_GENERAL, SG_INFO, "Splash screen progress " << text );
|
||||||
{
|
fgSetString("/sim/startup/splash-progress-text", text);
|
||||||
delete splash;
|
fgRequestRedraw();
|
||||||
splash = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fgSplashProgress ( const char *s )
|
|
||||||
{
|
|
||||||
progress_text = s;
|
|
||||||
fgRequestRedraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,24 +25,20 @@
|
||||||
#ifndef _SPLASH_HXX
|
#ifndef _SPLASH_HXX
|
||||||
#define _SPLASH_HXX
|
#define _SPLASH_HXX
|
||||||
|
|
||||||
|
#include <osg/Node>
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
# error This library requires C++
|
# error This library requires C++
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Initialize the splash screen
|
// Initialize the splash screen
|
||||||
void fgSplashInit ( const char *splash_texture );
|
void fgSplashInit ();
|
||||||
|
|
||||||
// Update the splash screen with alpha specified from 0.0 to 1.0
|
|
||||||
void fgSplashUpdate ( float alpha );
|
|
||||||
|
|
||||||
// Set progress information
|
// Set progress information
|
||||||
void fgSplashProgress ( const char *text );
|
void fgSplashProgress ( const char *text );
|
||||||
|
|
||||||
// Free texture memory
|
// Retrieve the splash screen node ...
|
||||||
void fgSplashExit ();
|
osg::Node* fgCreateSplashNode();
|
||||||
|
|
||||||
|
|
||||||
#endif // _SPLASH_HXX
|
#endif // _SPLASH_HXX
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ class FGScenery : public SGSubsystem {
|
||||||
// angle of sun relative to current local horizontal
|
// angle of sun relative to current local horizontal
|
||||||
double sun_angle;
|
double sun_angle;
|
||||||
|
|
||||||
// SSG scene graph
|
// scene graph
|
||||||
osg::ref_ptr<osg::Group> scene_graph;
|
osg::ref_ptr<osg::Group> scene_graph;
|
||||||
osg::ref_ptr<osg::Group> terrain_branch;
|
osg::ref_ptr<osg::Group> terrain_branch;
|
||||||
osg::ref_ptr<osg::Group> gnd_lights_root;
|
osg::ref_ptr<osg::Group> gnd_lights_root;
|
||||||
|
|
Loading…
Reference in a new issue