]> git.mxchange.org Git - flightgear.git/blobdiff - src/Cockpit/od_gauge.cxx
VoiceSynthesizer: add some test/debug properties
[flightgear.git] / src / Cockpit / od_gauge.cxx
index c6be269e4e5e5e3074c4b1d0d562f92914c92d36..883a17178036aabfa0a814506dca636056fd7cb2 100644 (file)
 
 #include <osgDB/FileNameUtils>
 
+#include <simgear/canvas/CanvasObjectPlacement.hxx>
 #include <simgear/scene/material/EffectGeode.hxx>
 #include <simgear/scene/util/RenderConstants.hxx>
 
 #include <Main/globals.hxx>
-#include <Viewer/renderer.hxx>
 #include <Scenery/scenery.hxx>
 #include "od_gauge.hxx"
 
 #include <cassert>
 
 //------------------------------------------------------------------------------
-FGODGauge::FGODGauge():
-  _size_x( -1 ),
-  _size_y( -1 ),
-  _view_width( -1 ),
-  _view_height( -1 ),
-  _use_image_coords( false ),
-  _use_stencil( false ),
-  _use_mipmapping( false ),
-  _coverage_samples( 0 ),
-  _color_samples( 0 ),
-  rtAvailable( false )
+FGODGauge::FGODGauge()
 {
-}
-
-//------------------------------------------------------------------------------
-FGODGauge::~FGODGauge()
-{
-  if( camera.valid() )
-    globals->get_renderer()->removeCamera(camera.get());
-}
-
-//------------------------------------------------------------------------------
-void FGODGauge::setSize(int size_x, int size_y)
-{
-  _size_x = size_x;
-  _size_y = size_y < 0 ? size_x : size_y;
-
-  if( texture.valid() )
-    texture->setTextureSize(_size_x, _size_x);
-}
-
-//----------------------------------------------------------------------------
-void FGODGauge::setViewSize(int width, int height)
-{
-  _view_width = width;
-  _view_height = height < 0 ? width : height;
-
-  if( camera )
-    updateCoordinateFrame();
-}
-
-//------------------------------------------------------------------------------
-void FGODGauge::useImageCoords(bool use)
-{
-  if( use == _use_image_coords )
-    return;
-
-  _use_image_coords = use;
-
-  if( texture )
-    updateCoordinateFrame();
-}
 
-//------------------------------------------------------------------------------
-void FGODGauge::useStencil(bool use)
-{
-  if( use == _use_stencil )
-    return;
-
-  _use_stencil = use;
-
-  if( texture )
-    updateStencil();
 }
 
 //------------------------------------------------------------------------------
-void FGODGauge::setSampling( bool mipmapping,
-                             int coverage_samples,
-                             int color_samples )
-{
-  if(    _use_mipmapping == mipmapping
-      && _coverage_samples == coverage_samples
-      && _color_samples == color_samples )
-    return;
-
-  _use_mipmapping = mipmapping;
-
-  if( color_samples > coverage_samples )
-  {
-    SG_LOG
-    (
-      SG_GL,
-      SG_WARN,
-      "FGODGauge::setSampling: color_samples > coverage_samples not allowed!"
-    );
-    color_samples = coverage_samples;
-  }
-
-  _coverage_samples = coverage_samples;
-  _color_samples = color_samples;
-
-  updateSampling();
-}
-
-//------------------------------------------------------------------------------
-void FGODGauge::setRender(bool render)
-{
-  // Only the far camera should trigger this texture to be rendered.
-  camera->setNodeMask(render ? simgear::BACKGROUND_BIT : 0);
-}
-
-//------------------------------------------------------------------------------
-bool FGODGauge::serviceable(void) 
-{
-  return rtAvailable;
-}
-
-//------------------------------------------------------------------------------
-void FGODGauge::allocRT(osg::NodeCallback* camera_cull_callback)
-{
-  camera = new osg::Camera;
-  camera->setDataVariance(osg::Object::DYNAMIC);
-  camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
-  camera->setRenderOrder(osg::Camera::PRE_RENDER);
-  camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 0.0f));
-  camera->setClearStencil(0);
-  camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT,
-                                             osg::Camera::FRAME_BUFFER );
-
-  if( camera_cull_callback )
-    camera->setCullCallback(camera_cull_callback);
-
-  setRender(true);
-  updateCoordinateFrame();
-  updateStencil();
-
-  osg::StateSet* stateSet = camera->getOrCreateStateSet();
-  stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
-  stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
-  stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
-  stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
-  stateSet->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,
-          osg::PolygonMode::FILL),
-          osg::StateAttribute::ON);
-  stateSet->setAttributeAndModes(new osg::AlphaFunc(osg::AlphaFunc::GREATER,
-          0.0f),
-          osg::StateAttribute::ON);
-  stateSet->setAttribute(new osg::ShadeModel(osg::ShadeModel::FLAT));
-  stateSet->setAttributeAndModes(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
-          osg::BlendFunc::ONE_MINUS_SRC_ALPHA),
-          osg::StateAttribute::ON);
-  if( !texture )
-  {
-    texture = new osg::Texture2D;
-    texture->setTextureSize(_size_x, _size_y);
-    texture->setInternalFormat(GL_RGBA);
-  }
-
-  updateSampling();
-
-  globals->get_renderer()->addCamera(camera.get(), false);
-  rtAvailable = true;
-}
-
-//------------------------------------------------------------------------------
-void FGODGauge::updateCoordinateFrame()
-{
-  assert( camera );
-
-  if( _view_width < 0 )
-    _view_width = _size_x;
-  if( _view_height < 0 )
-    _view_height = _size_y;
-
-  camera->setViewport(0, 0, _size_x, _size_y);
-
-  if( _use_image_coords )
-    camera->setProjectionMatrix(
-      osg::Matrix::ortho2D(0, _view_width, _view_height, 0)
-    );
-  else
-    camera->setProjectionMatrix(
-      osg::Matrix::ortho2D( -_view_width/2.,  _view_width/2.,
-                            -_view_height/2., _view_height/2. )
-    );
-}
-
-//------------------------------------------------------------------------------
-void FGODGauge::updateStencil()
-{
-  assert( camera );
-
-  GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
-
-  if( _use_stencil)
-  {
-    camera->attach( osg::Camera::PACKED_DEPTH_STENCIL_BUFFER,
-                     GL_DEPTH_STENCIL_EXT );
-    mask |= GL_STENCIL_BUFFER_BIT;
-  }
-  else
-  {
-    camera->detach(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER);
-  }
-
-  camera->setClearMask(mask);
-}
-
-//------------------------------------------------------------------------------
-void FGODGauge::updateSampling()
+FGODGauge::~FGODGauge()
 {
-  assert( camera );
-  assert( texture );
 
-  texture->setFilter(
-    osg::Texture2D::MIN_FILTER,
-    _use_mipmapping ? osg::Texture2D::LINEAR_MIPMAP_LINEAR
-                    : osg::Texture2D::LINEAR
-  );
-  camera->attach(
-    osg::Camera::COLOR_BUFFER,
-    texture.get(),
-    0, 0,
-    _use_mipmapping,
-    _coverage_samples,
-    _color_samples
-  );
 }
 
 /**
@@ -282,24 +74,32 @@ class ReplaceStaticTextureVisitor:
 {
   public:
 
+    typedef osg::ref_ptr<osg::Group> GroupPtr;
+    typedef osg::ref_ptr<osg::Material> MaterialPtr;
+
     ReplaceStaticTextureVisitor( const char* name,
                                  osg::Texture2D* new_texture ):
         osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
         _tex_name( osgDB::getSimpleFileName(name) ),
-        _new_texture(new_texture)
+        _new_texture(new_texture),
+        _cull_callback(0)
     {}
 
-    ReplaceStaticTextureVisitor( const SGPropertyNode* placement,
+    ReplaceStaticTextureVisitor( SGPropertyNode* placement,
                                  osg::Texture2D* new_texture,
-                                 osg::NodeCallback* cull_callback = 0 ):
+                                 osg::NodeCallback* cull_callback = 0,
+                                 const simgear::canvas::CanvasWeakPtr& canvas =
+                                   simgear::canvas::CanvasWeakPtr() ):
         osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
         _tex_name( osgDB::getSimpleFileName(
           placement->getStringValue("texture"))
         ),
         _node_name( placement->getStringValue("node") ),
         _parent_name( placement->getStringValue("parent") ),
+        _node(placement),
         _new_texture(new_texture),
-        _cull_callback(cull_callback)
+        _cull_callback(cull_callback),
+        _canvas(canvas)
     {
       if(    _tex_name.empty()
           && _node_name.empty()
@@ -317,7 +117,7 @@ class ReplaceStaticTextureVisitor:
      * Get a list of groups which have been inserted into the scene graph to
      * replace the given texture
      */
-    canvas::Placements& getPlacements()
+    simgear::canvas::Placements& getPlacements()
     {
       return _placements;
     }
@@ -333,7 +133,7 @@ class ReplaceStaticTextureVisitor:
         return;
 
       osg::Group *parent = node.getParent(0);
-      if( !_node_name.empty() && parent->getName() != _node_name )
+      if( !_node_name.empty() && getNodeName(*parent) != _node_name )
         return;
 
       if( !_parent_name.empty() )
@@ -383,7 +183,7 @@ class ReplaceStaticTextureVisitor:
 
         // insert a new group between the geode an it's parent which overrides
         // the texture
-        osg::ref_ptr<osg::Group> group = new osg::Group;
+        GroupPtr group = new osg::Group;
         group->setName("canvas texture group");
         group->addChild(eg);
         parent->removeChild(eg);
@@ -392,16 +192,16 @@ class ReplaceStaticTextureVisitor:
         if( _cull_callback )
           group->setCullCallback(_cull_callback);
 
-        _placements.push_back(
-          canvas::PlacementPtr(new ObjectPlacement(group))
-        );
-
         osg::StateSet* stateSet = group->getOrCreateStateSet();
         stateSet->setTextureAttribute( unit, _new_texture,
                                              osg::StateAttribute::OVERRIDE );
         stateSet->setTextureMode( unit, GL_TEXTURE_2D,
                                         osg::StateAttribute::ON );
 
+        _placements.push_back( simgear::canvas::PlacementPtr(
+          new simgear::canvas::ObjectPlacement(_node, group, _canvas)
+        ));
+
         SG_LOG
         (
           SG_GL,
@@ -417,63 +217,87 @@ class ReplaceStaticTextureVisitor:
 
   protected:
 
-    class ObjectPlacement:
-      public canvas::Placement
-    {
-      public:
-        ObjectPlacement(osg::ref_ptr<osg::Group> group):
-          _group(group)
-        {}
-
-        /**
-         * Remove placement from the scene
-         */
-        virtual ~ObjectPlacement()
-        {
-          assert( _group->getNumChildren() == 1 );
-          osg::Node *child = _group->getChild(0);
-
-          if( _group->getNumParents() )
-          {
-            osg::Group *parent = _group->getParent(0);
-            parent->addChild(child);
-            parent->removeChild(_group);
-          }
-
-          _group->removeChild(child);
-        }
-
-      private:
-        osg::ref_ptr<osg::Group> _group;
-    };
-
     std::string _tex_name,      ///<! Name of texture to be replaced
                 _node_name,     ///<! Only replace if node name matches
                 _parent_name;   ///<! Only replace if any parent node matches
                                 ///   given name (all the tree upwards)
+
+    SGPropertyNode_ptr  _node;
     osg::Texture2D     *_new_texture;
     osg::NodeCallback  *_cull_callback;
 
-    canvas::Placements _placements;
+    simgear::canvas::CanvasWeakPtr  _canvas;
+    simgear::canvas::Placements     _placements;
+
+    const std::string& getNodeName(const osg::Node& node) const
+    {
+      if( !node.getName().empty() )
+        return node.getName();
+
+      // Special handling for pick animation which clears the name of the object
+      // and instead sets the name of a parent group with one or two groups
+      // attached (one for normal rendering and one for the picking highlight).
+      osg::Group const* parent = node.getParent(0);
+      if( parent->getName() == "pick render group" )
+        return parent->getParent(0)->getName();
+
+      return node.getName();
+    }
 };
 
 //------------------------------------------------------------------------------
-canvas::Placements FGODGauge::set_texture( const char* name,
-                                           osg::Texture2D* new_texture )
+simgear::canvas::Placements
+FGODGauge::set_texture( osg::Node* branch,
+                        const char * name,
+                        osg::Texture2D* new_texture )
 {
-  osg::Group* root = globals->get_scenery()->get_aircraft_branch();
   ReplaceStaticTextureVisitor visitor(name, new_texture);
-  root->accept(visitor);
+  branch->accept(visitor);
   return visitor.getPlacements();
 }
 
 //------------------------------------------------------------------------------
-canvas::Placements FGODGauge::set_texture( const SGPropertyNode* placement,
-                                           osg::Texture2D* new_texture,
-                                           osg::NodeCallback* cull_callback )
+simgear::canvas::Placements
+FGODGauge::set_aircraft_texture( const char* name,
+                                 osg::Texture2D* new_texture )
+{
+  return set_texture
+  (
+    globals->get_scenery()->get_aircraft_branch(),
+    name,
+    new_texture
+  );
+}
+
+//------------------------------------------------------------------------------
+simgear::canvas::Placements
+FGODGauge::set_texture( osg::Node* branch,
+                        SGPropertyNode* placement,
+                        osg::Texture2D* new_texture,
+                        osg::NodeCallback* cull_callback,
+                        const simgear::canvas::CanvasWeakPtr& canvas )
 {
-  osg::Group* root = globals->get_scenery()->get_aircraft_branch();
-  ReplaceStaticTextureVisitor visitor(placement, new_texture, cull_callback);
-  root->accept(visitor);
+  ReplaceStaticTextureVisitor visitor( placement,
+                                       new_texture,
+                                       cull_callback,
+                                       canvas );
+  branch->accept(visitor);
   return visitor.getPlacements();
 }
+
+//------------------------------------------------------------------------------
+simgear::canvas::Placements
+FGODGauge::set_aircraft_texture( SGPropertyNode* placement,
+                                 osg::Texture2D* new_texture,
+                                 osg::NodeCallback* cull_callback,
+                                 const simgear::canvas::CanvasWeakPtr& canvas )
+{
+  return set_texture
+  (
+    globals->get_scenery()->get_aircraft_branch(),
+    placement,
+    new_texture,
+    cull_callback,
+    canvas
+  );
+}