]> git.mxchange.org Git - simgear.git/commitdiff
ODGauge/Canvas: add option "additive-blend" to use additive alpha blending
authorThomas Geymayer <tomgey@gmail.com>
Thu, 28 Feb 2013 21:02:11 +0000 (22:02 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Thu, 28 Feb 2013 21:04:16 +0000 (22:04 +0100)
simgear/canvas/Canvas.cxx
simgear/canvas/ODGauge.cxx
simgear/canvas/ODGauge.hxx

index 4117c7afcba133df326fb34688abf3d4d2d03d9b..cb8d6917d25ab3d785080b8773f957fd573c5626 100644 (file)
@@ -445,6 +445,10 @@ namespace canvas
       {
         _sampling_dirty = true;
       }
+      else if( node->getNameString() == "additive-blend" )
+      {
+        _texture.useAdditiveBlend( node->getBoolValue() );
+      }
       else if( node->getNameString() == "render-always" )
       {
         _render_always = node->getBoolValue();
index b59efc6a0f762d82608c687dca564fccfa97ce49..7a252721195fc26d31c8c53ad178a6760d754ffa 100644 (file)
@@ -57,12 +57,9 @@ namespace canvas
     _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 )
   {
 
   }
@@ -104,39 +101,34 @@ namespace canvas
   //----------------------------------------------------------------------------
   void ODGauge::useImageCoords(bool use)
   {
-    if( use == _use_image_coords )
-      return;
-
-    _use_image_coords = use;
-
-    if( texture )
+    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
@@ -164,7 +156,7 @@ namespace canvas
   //----------------------------------------------------------------------------
   bool ODGauge::serviceable(void)
   {
-    return rtAvailable;
+    return _flags & AVAILABLE;
   }
 
   //----------------------------------------------------------------------------
@@ -196,13 +188,10 @@ 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;
@@ -211,11 +200,12 @@ namespace canvas
     }
 
     updateSampling();
+    updateBlendMode();
 
     if( _system_adapter )
       _system_adapter->addCamera(camera.get());
 
-    rtAvailable = true;
+    _flags |= AVAILABLE;
   }
 
   //----------------------------------------------------------------------------
@@ -234,7 +224,17 @@ namespace canvas
     camera.release();
     texture.release();
 
-    rtAvailable = false;
+    _flags &= ~AVAILABLE;
+  }
+
+  //----------------------------------------------------------------------------
+  bool ODGauge::updateFlag(Flags flag, bool enable)
+  {
+    if( (_flags & flag) == enable )
+      return false;
+
+    _flags ^= flag;
+    return true;
   }
 
   //----------------------------------------------------------------------------
@@ -249,7 +249,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 +267,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 +289,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
index 3005132c10d9b7f66aefb93422d92b10c03e4189..fc3d8b770d1c41204ed93f142f6e19479242348b 100644 (file)
@@ -91,6 +91,12 @@ namespace canvas
        */
       void useStencil(bool use = true);
 
+      /**
+       * Enable/Disable additive alpha blending (Can improve results with
+       * transparent background)
+       */
+      void useAdditiveBlend(bool use = true);
+
       /**
        * Set sampling parameters for mipmapping and coverage sampling
        * antialiasing.
@@ -134,21 +140,31 @@ namespace canvas
           _size_y,
           _view_width,
           _view_height;
-      bool _use_image_coords,
-           _use_stencil,
-           _use_mipmapping;
+
+      enum Flags
+      {
+        AVAILABLE           = 1,
+        USE_IMAGE_COORDS    = AVAILABLE << 1,
+        USE_STENCIL         = USE_IMAGE_COORDS << 1,
+        USE_MIPMAPPING      = USE_STENCIL << 1,
+        USE_ADDITIVE_BLEND  = USE_MIPMAPPING << 1
+      };
+
+      uint32_t _flags;
 
       // Multisampling parameters
       int  _coverage_samples,
            _color_samples;
 
-      bool rtAvailable;
       osg::ref_ptr<osg::Camera> camera;
       osg::ref_ptr<osg::Texture2D> texture;
 
+      bool updateFlag(Flags flag, bool enable);
+
       void updateCoordinateFrame();
       void updateStencil();
       void updateSampling();
+      void updateBlendMode();
 
   };