20,741
edits
m (→Adding draw masks for Canvas: http://forum.flightgear.org/viewtopic.php?f=42&t=24728&p=225846&hilit=masks#p225846) |
m (→Adding draw masks for Canvas: http://forum.flightgear.org/viewtopic.php?f=5&t=23781&p=231142&hilit=masks#p231142) |
||
| Line 239: | Line 239: | ||
Equally, disabling the (main) aircraft, will tell you if it's the complexity of the 777 3D model (cockpit). | Equally, disabling the (main) aircraft, will tell you if it's the complexity of the 777 3D model (cockpit). | ||
This would work analogous to our existing "draw-masks", (as per the minimal startup profile detailed on the wiki) - basically, more and more features would get dedicated properties with draw-masks to disable/enable rendering and optionally customize things - this isn't too difficult to do, and it doesn't necessarily involve touching tons of STG/BTG files - it's mainly a change that would involve SimGear/FG, so that buildings (and other heavy stuff) would be loaded into dedicated sub-scene graph that can be easily disabled using an osg::switch node - here's a code snippet demonstrating the concept by disabling rendering of the sun/sky. | |||
We've used these for doing some more profiling on the netbook that I mentioned to help better understand where performance is spent, not just in terms of subsystems, but also at the rendering level (PUI!) -this is line with James' original "draw-masks" commit and uses the same property location for new draw masks - I think this could be a useful extension for various reasons, because we can simply keep stuff disabled while booting - and also use it for troubleshooting. | |||
<syntaxhighlight lang="diff"> | |||
diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx | |||
index 2c4d5c7..d3ba9a6 100644 | |||
--- a/src/Viewer/renderer.cxx | |||
+++ b/src/Viewer/renderer.cxx | |||
@@ -82,7 +82,10 @@ | |||
#include <simgear/scene/tgdb/pt_lights.hxx> | |||
#include <simgear/scene/tgdb/userdata.hxx> | |||
#include <simgear/structure/OSGUtils.hxx> | |||
+ | |||
#include <simgear/props/props.hxx> | |||
+#include <simgear/props/propertyObject.hxx> | |||
+ | |||
#include <simgear/timing/sg_time.hxx> | |||
#include <simgear/ephemeris/ephemeris.hxx> | |||
#include <simgear/math/sg_random.h> | |||
@@ -380,9 +383,60 @@ public: | |||
static bool scenery_enabled; | |||
}; | |||
- | |||
bool FGScenerySwitchCallback::scenery_enabled = false; | |||
+// update callback for the sky switch node | |||
+struct FGSkySwitchCallback : public osg::NodeCallback { | |||
+ FGSkySwitchCallback() : _enabled("/sim/rendering/draw-mask/sky") {} | |||
+ | |||
+ virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) | |||
+ { | |||
+ assert(dynamic_cast<osg::Switch*>(node)); | |||
+ osg::Switch* sw = static_cast<osg::Switch*>(node); | |||
+ | |||
+ sw->setValue(0, _enabled); | |||
+ if (!_enabled) | |||
+ return; | |||
+ traverse(node, nv); | |||
+ } | |||
+private: | |||
+simgear::PropertyObject<bool> _enabled; | |||
+}; | |||
+ | |||
+// update callback for the GUI (old) switch node | |||
+struct FGOldGUISwitchCallback : public osg::NodeCallback { | |||
+ FGOldGUISwitchCallback() : _enabled("/sim/rendering/draw-mask/old-gui") {} | |||
+ virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) | |||
+ { | |||
+ assert(dynamic_cast<osg::Switch*>(node)); | |||
+ osg::Switch* sw = static_cast<osg::Switch*>(node); | |||
+ | |||
+ sw->setValue(0, _enabled); | |||
+ if (!_enabled) | |||
+ return; | |||
+ traverse(node, nv); | |||
+ } | |||
+private: | |||
+simgear::PropertyObject<bool> _enabled; | |||
+}; | |||
+ | |||
+// update callback for the GUI (old) switch node | |||
+struct FGSunlightSwitchCallback : public osg::NodeCallback { | |||
+ FGSunlightSwitchCallback() : _enabled("/sim/rendering/draw-mask/sunlight") {} | |||
+ virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) | |||
+ { | |||
+ assert(dynamic_cast<osg::Switch*>(node)); | |||
+ osg::Switch* sw = static_cast<osg::Switch*>(node); | |||
+ | |||
+ sw->setValue(0, _enabled); | |||
+ if (!_enabled) | |||
+ return; | |||
+ traverse(node, nv); | |||
+ } | |||
+private: | |||
+simgear::PropertyObject<bool> _enabled; | |||
+}; | |||
+ | |||
FGRenderer::FGRenderer() : | |||
_sky(NULL), | |||
_ambientFactor( new osg::Uniform( "fg_SunAmbientColor", osg::Vec4f() ) ), | |||
@@ -1483,7 +1537,8 @@ FGRenderer::setupView( void ) | |||
lightSource->setLocalStateSetModes(osg::StateAttribute::ON); | |||
lightSource->setUpdateCallback(new FGLightSourceUpdateCallback); | |||
_viewerSceneRoot->addChild(lightSource); | |||
- | |||
+ | |||
+ | |||
// we need a white diffuse light for the phase of the moon | |||
osg::ref_ptr<LightSource> sunLight = new osg::LightSource; | |||
sunLight->setName("sunLightSource"); | |||
@@ -1501,7 +1556,11 @@ FGRenderer::setupView( void ) | |||
sunLight->addChild(skyGroup); | |||
if ( _classicalRenderer ) { | |||
- _root->addChild(sunLight); | |||
+ osg::Switch *sw = new osg::Switch; | |||
+ sw->setName("sunLightSwitch"); | |||
+ sw->setUpdateCallback( new FGSunlightSwitchCallback); | |||
+ sw->addChild(sunLight); | |||
+ _root->addChild(sw); | |||
} | |||
osg::Group* sceneGroup = globals->get_scenery()->get_scene_graph(); | |||
@@ -1531,19 +1590,25 @@ FGRenderer::setupView( void ) | |||
stateSet->setAttributeAndModes(fog); | |||
stateSet->setUpdateCallback(new FGFogEnableUpdateCallback); | |||
+ | |||
// plug in the GUI | |||
osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault()); | |||
if (guiCamera) { | |||
+ osg::Switch* sw = new osg::Switch; | |||
+ sw->setName("OldGUISwitch"); | |||
+ sw->setUpdateCallback(new FGOldGUISwitchCallback); | |||
+ | |||
osg::Geode* geode = new osg::Geode; | |||
geode->addDrawable(new SGHUDDrawable); | |||
geode->addDrawable(new SGPuDrawable); | |||
+ sw->addChild(geode); | |||
+ sw->addChild( FGPanelNode::create2DPanelNode() ); | |||
// Draw first (eg. before Canvas GUI) | |||
- guiCamera->insertChild(0, geode); | |||
- guiCamera->insertChild(0, FGPanelNode::create2DPanelNode()); | |||
+ guiCamera->insertChild(0, sw); | |||
} | |||
- osg::Switch* sw = new osg::Switch; | |||
+ osg::Switch *sw = new osg::Switch; | |||
sw->setName("scenerySwitch"); | |||
sw->setUpdateCallback(new FGScenerySwitchCallback); | |||
sw->addChild(_root.get()); | |||
@@ -1552,8 +1617,13 @@ FGRenderer::setupView( void ) | |||
// 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 ) { | |||
- _viewerSceneRoot->addChild(_sky->getCloudRoot()); | |||
- _viewerSceneRoot->addChild(FGCreateRedoutNode()); | |||
+ sw = new osg::Switch; | |||
+ sw->setName("skySwitch"); | |||
+ sw->setUpdateCallback(new FGSkySwitchCallback); | |||
+ sw->addChild(_sky->getCloudRoot()); | |||
+ sw->addChild(FGCreateRedoutNode()); | |||
+ | |||
+ _viewerSceneRoot->addChild(sw); | |||
} | |||
// Attach empty program to the scene root so that shader programs | |||
@@ -1625,7 +1695,8 @@ FGRenderer::update( ) { | |||
: osg::Vec4(0, 0, 0, 1); | |||
camera->setClearColor(clear_color); | |||
- updateSky(); | |||
+ if (fgGetBool("/sim/rendering/draw-mask/sky",true)) | |||
+ updateSky(); | |||
// need to call the update visitor once | |||
_frameStamp->setCalendarTime(*globals->get_time_params()->getGmt()); | |||
diff --git a/preferences.xml b/preferences.xml | |||
index dbbbe2a..bc35ef3 100644 | |||
--- a/preferences.xml | |||
+++ b/preferences.xml | |||
@@ -224,10 +224,13 @@ Started September 2000 by David Megginson, david@megginson.com | |||
non-cockpit + aircraft elements. Use draw-mask instead. --> | |||
<draw-otw type="bool">true</draw-otw> | |||
<draw-mask> | |||
+ <sunlight type="bool">true</sunlight> | |||
<terrain type="bool">true</terrain> | |||
<models type="bool">true</models> | |||
<aircraft type="bool">true</aircraft> | |||
<clouds type="bool">true</clouds> | |||
+ <sky type="bool">true</sky> | |||
+ <old-gui type="bool">true</old-gui> | |||
</draw-mask> | |||
<shadows-ac type="bool" userarchive="y">false</shadows-ac> | |||
</syntaxhighlight> | |||
We are probably going to add a few more draw-masks, also for Canvas - not because I believe that we need to run FG without Canvas :lol: , but to provide stats/evidence for benchmarking purposes, i.e. we can tell people to use those draw masks to disable all CanvasGUI/CanvasScenery/CanvasAircraft rendering and watch their frame rate/spacing accordingly. | |||
The following patch is intended to help determine the rendering overhead of Canvas by adding optional draw-masks for disabling rendering of Canvas textures via their corresponding placements (aircraft, scenery and GUI): | The following patch is intended to help determine the rendering overhead of Canvas by adding optional draw-masks for disabling rendering of Canvas textures via their corresponding placements (aircraft, scenery and GUI): | ||
| Line 245: | Line 427: | ||
Under the hood, the corresponding Nasal/C++ code updating Canvas textures would obviously still be running - it would just be rendering that is explicitly disabled here. | Under the hood, the corresponding Nasal/C++ code updating Canvas textures would obviously still be running - it would just be rendering that is explicitly disabled here. | ||
For the [[FGCanvas]] mode, this just means that sky/sunlight and PUI rendering can be completely disabled for even better performance/appearance, i.e. Nasal/Canvas are up and running in under 5 seconds here normally. Likewise, this is a good thing for debugging and regression testing, i.e. to keep certain rendering features completely disabled - for example so that only Canvas related OSG/OpenGL calls show up in the gDebugger profile, i.e. much more fine-grained info, without having to patch FG. | |||
=== Hooking up Canvas to the Osg Stats === | === Hooking up Canvas to the Osg Stats === | ||