]> git.mxchange.org Git - simgear.git/blobdiff - simgear/canvas/ODGauge.cxx
Add simple keyboard event demo application.
[simgear.git] / simgear / canvas / ODGauge.cxx
index b59efc6a0f762d82608c687dca564fccfa97ce49..5c547eafa1af784ddc0cfffb46f278bad1cae190 100644 (file)
@@ -29,6 +29,7 @@
 #endif
 
 #include "ODGauge.hxx"
+#include "Canvas.hxx"
 #include "CanvasSystemAdapter.hxx"
 
 #include <simgear/debug/logstream.hxx>
@@ -43,6 +44,7 @@
 #include <osg/ShadeModel>
 #include <osg/StateSet>
 #include <osg/FrameBufferObject> // for GL_DEPTH_STENCIL_EXT on Windows
+#include <osgUtil/RenderBin>
 
 #include <cassert>
 
@@ -51,18 +53,67 @@ namespace simgear
 namespace canvas
 {
 
+  class PreOrderBin:
+    public osgUtil::RenderBin
+  {
+    public:
+
+      PreOrderBin()
+      {}
+      PreOrderBin( const RenderBin& rhs,
+                   const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY ):
+        RenderBin(rhs, copyop)
+      {}
+
+      virtual osg::Object* cloneType() const
+      {
+        return new PreOrderBin();
+      }
+      virtual osg::Object* clone(const osg::CopyOp& copyop) const
+      {
+        return new PreOrderBin(*this,copyop);
+      }
+      virtual bool isSameKindAs(const osg::Object* obj) const
+      {
+        return dynamic_cast<const PreOrderBin*>(obj) != 0L;
+      }
+      virtual const char* className() const
+      {
+        return "PreOrderBin";
+      }
+
+      virtual void sort()
+      {
+        // Do not sort to keep traversal order...
+      }
+  };
+
+#ifndef OSG_INIT_SINGLETON_PROXY
+  /**
+   * http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk/include/osg/Object
+   *
+   * Helper macro that creates a static proxy object to call singleton function
+   * on it's construction, ensuring that the singleton gets initialized at
+   * startup.
+   */
+#  define OSG_INIT_SINGLETON_PROXY(ProxyName, Func)\
+          static struct ProxyName{ ProxyName() { Func; } } s_##ProxyName;
+#endif
+
+  OSG_INIT_SINGLETON_PROXY(
+    PreOrderBinProxy,
+    (osgUtil::RenderBin::addRenderBinPrototype("PreOrderBin", new PreOrderBin))
+  );
+
   //----------------------------------------------------------------------------
   ODGauge::ODGauge():
     _size_x( -1 ),
     _size_y( -1 ),
     _view_width( -1 ),
     _view_height( -1 ),
-    _use_image_coords( false ),
-    _use_stencil( false ),
-    _use_mipmapping( false ),
+    _flags(0),
     _coverage_samples( 0 ),
-    _color_samples( 0 ),
-    rtAvailable( false )
+    _color_samples( 0 )
   {
 
   }
@@ -73,12 +124,6 @@ namespace canvas
     clear();
   }
 
-  //----------------------------------------------------------------------------
-  void ODGauge::setSystemAdapter(const SystemAdapterPtr& system_adapter)
-  {
-    _system_adapter = system_adapter;
-  }
-
   //----------------------------------------------------------------------------
   void ODGauge::setSize(int size_x, int size_y)
   {
@@ -102,41 +147,42 @@ namespace canvas
   }
 
   //----------------------------------------------------------------------------
-  void ODGauge::useImageCoords(bool use)
+  osg::Vec2s ODGauge::getViewSize() const
   {
-    if( use == _use_image_coords )
-      return;
-
-    _use_image_coords = use;
+    return osg::Vec2s(_view_width, _view_height);
+  }
 
-    if( texture )
+  //----------------------------------------------------------------------------
+  void ODGauge::useImageCoords(bool use)
+  {
+    if( updateFlag(USE_IMAGE_COORDS, use) && texture )
       updateCoordinateFrame();
   }
 
   //----------------------------------------------------------------------------
   void ODGauge::useStencil(bool use)
   {
-    if( use == _use_stencil )
-      return;
-
-    _use_stencil = use;
-
-    if( texture )
+    if( updateFlag(USE_STENCIL, use) && texture )
       updateStencil();
   }
 
+  //----------------------------------------------------------------------------
+  void ODGauge::useAdditiveBlend(bool use)
+  {
+    if( updateFlag(USE_ADDITIVE_BLEND, use) && camera )
+      updateBlendMode();
+  }
+
   //----------------------------------------------------------------------------
   void ODGauge::setSampling( bool mipmapping,
-                               int coverage_samples,
-                               int color_samples )
+                             int coverage_samples,
+                             int color_samples )
   {
-    if(    _use_mipmapping == mipmapping
+    if(    !updateFlag(USE_MIPMAPPING, mipmapping)
         && _coverage_samples == coverage_samples
         && _color_samples == color_samples )
       return;
 
-    _use_mipmapping = mipmapping;
-
     if( color_samples > coverage_samples )
     {
       SG_LOG
@@ -162,9 +208,9 @@ namespace canvas
   }
 
   //----------------------------------------------------------------------------
-  bool ODGauge::serviceable(void)
+  bool ODGauge::serviceable() const
   {
-    return rtAvailable;
+    return _flags & AVAILABLE;
   }
 
   //----------------------------------------------------------------------------
@@ -196,26 +242,25 @@ namespace canvas
                             osg::PolygonMode::FILL ),
       osg::StateAttribute::ON );
     stateSet->setAttributeAndModes(
-      new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.0f),
+      new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.001f),
       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->setResizeNonPowerOfTwoHint(false);
       texture->setTextureSize(_size_x, _size_y);
       texture->setInternalFormat(GL_RGBA);
     }
 
     updateSampling();
+    updateBlendMode();
 
-    if( _system_adapter )
-      _system_adapter->addCamera(camera.get());
+    if( Canvas::getSystemAdapter() )
+      Canvas::getSystemAdapter()->addCamera(camera.get());
 
-    rtAvailable = true;
+    _flags |= AVAILABLE;
   }
 
   //----------------------------------------------------------------------------
@@ -229,12 +274,22 @@ namespace canvas
   //----------------------------------------------------------------------------
   void ODGauge::clear()
   {
-    if( camera.valid() && _system_adapter )
-      _system_adapter->removeCamera(camera.get());
+    if( camera.valid() && Canvas::getSystemAdapter() )
+      Canvas::getSystemAdapter()->removeCamera(camera.get());
     camera.release();
     texture.release();
 
-    rtAvailable = false;
+    _flags &= ~AVAILABLE;
+  }
+
+  //----------------------------------------------------------------------------
+  bool ODGauge::updateFlag(Flags flag, bool enable)
+  {
+    if( bool(_flags & flag) == enable )
+      return false;
+
+    _flags ^= flag;
+    return true;
   }
 
   //----------------------------------------------------------------------------
@@ -249,7 +304,7 @@ namespace canvas
 
     camera->setViewport(0, 0, _size_x, _size_y);
 
-    if( _use_image_coords )
+    if( _flags & USE_IMAGE_COORDS )
       camera->setProjectionMatrix(
         osg::Matrix::ortho2D(0, _view_width, _view_height, 0)
       );
@@ -267,7 +322,7 @@ namespace canvas
 
     GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
 
-    if( _use_stencil)
+    if( _flags & USE_STENCIL )
     {
       camera->attach( osg::Camera::PACKED_DEPTH_STENCIL_BUFFER,
                        GL_DEPTH_STENCIL_EXT );
@@ -289,18 +344,36 @@ namespace canvas
 
     texture->setFilter(
       osg::Texture2D::MIN_FILTER,
-      _use_mipmapping ? osg::Texture2D::LINEAR_MIPMAP_LINEAR
-                      : osg::Texture2D::LINEAR
+      (_flags & USE_MIPMAPPING) ? osg::Texture2D::LINEAR_MIPMAP_LINEAR
+                                : osg::Texture2D::LINEAR
     );
     camera->attach(
       osg::Camera::COLOR_BUFFER,
       texture.get(),
       0, 0,
-      _use_mipmapping,
+      _flags & USE_MIPMAPPING,
       _coverage_samples,
       _color_samples
     );
   }
 
+  //----------------------------------------------------------------------------
+  void ODGauge::updateBlendMode()
+  {
+    assert( camera );
+
+    camera->getOrCreateStateSet()
+      ->setAttributeAndModes
+      (
+        (_flags & USE_ADDITIVE_BLEND)
+          ? new osg::BlendFunc( osg::BlendFunc::SRC_ALPHA,
+                                osg::BlendFunc::ONE_MINUS_SRC_ALPHA,
+                                osg::BlendFunc::ONE,
+                                osg::BlendFunc::ONE )
+          : new osg::BlendFunc( osg::BlendFunc::SRC_ALPHA,
+                                osg::BlendFunc::ONE_MINUS_SRC_ALPHA )
+      );
+  }
+
 } // namespace canvas
 } // namespace simgear