]> git.mxchange.org Git - simgear.git/blobdiff - simgear/canvas/ODGauge.cxx
Refactor Canvas and add some helpers.
[simgear.git] / simgear / canvas / ODGauge.cxx
index d0c5e2c9556e2d7eef7d01d99aece680be5eaaa9..8b27c06f8727240d91db990a4173f874e1694697 100644 (file)
 // Supports now multisampling/mipmapping, usage of the stencil buffer and placing
 // the texture in the scene by certain filter criteria
 //
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
 //
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//
+// Library General Public License for more details.
 //
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
 
 #ifdef HAVE_CONFIG_H
 #  include <simgear_config.h>
 #endif
 
+#include "ODGauge.hxx"
+#include "CanvasSystemAdapter.hxx"
+
+#include <simgear/debug/logstream.hxx>
+#include <simgear/scene/util/RenderConstants.hxx>
+
 #include <osg/Texture2D>
 #include <osg/AlphaFunc>
 #include <osg/BlendFunc>
 #include <osg/StateSet>
 #include <osg/FrameBufferObject> // for GL_DEPTH_STENCIL_EXT on Windows
 
-#include <simgear/debug/logstream.hxx>
-#include <simgear/scene/util/RenderConstants.hxx>
-#include "ODGauge.hxx"
-
 #include <cassert>
 
 namespace simgear
 {
-
-//------------------------------------------------------------------------------
-ODGauge::ODGauge( const CameraRegistrationCallback& cb_camera_add,
-                  const CameraRegistrationCallback& cb_camera_remove ):
-  _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 ),
-  _cb_cam_add( cb_camera_add ),
-  _cb_cam_remove( cb_camera_remove )
+namespace canvas
 {
 
-}
+  //----------------------------------------------------------------------------
+  ODGauge::ODGauge():
+    _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 )
+  {
 
-//------------------------------------------------------------------------------
-ODGauge::~ODGauge()
-{
-  if( camera.valid() )
-    _cb_cam_remove(camera.get());
-}
+  }
 
-//------------------------------------------------------------------------------
-void ODGauge::setSize(int size_x, int size_y)
-{
-  _size_x = size_x;
-  _size_y = size_y < 0 ? size_x : size_y;
+  //----------------------------------------------------------------------------
+  ODGauge::~ODGauge()
+  {
+    if( camera.valid() && _system_adapter )
+      _system_adapter->removeCamera(camera.get());
+  }
 
-  if( texture.valid() )
-    texture->setTextureSize(_size_x, _size_x);
-}
+  //----------------------------------------------------------------------------
+  void ODGauge::setSystemAdapter(const SystemAdapterPtr& system_adapter)
+  {
+    _system_adapter = system_adapter;
+  }
 
-//----------------------------------------------------------------------------
-void ODGauge::setViewSize(int width, int height)
-{
-  _view_width = width;
-  _view_height = height < 0 ? width : height;
+  //----------------------------------------------------------------------------
+  void ODGauge::setSize(int size_x, int size_y)
+  {
+    _size_x = size_x;
+    _size_y = size_y < 0 ? size_x : size_y;
 
-  if( camera )
-    updateCoordinateFrame();
-}
+    if( texture.valid() )
+      texture->setTextureSize(_size_x, _size_x);
+  }
 
-//------------------------------------------------------------------------------
-void ODGauge::useImageCoords(bool use)
-{
-  if( use == _use_image_coords )
-    return;
+  //----------------------------------------------------------------------------
+  void ODGauge::setViewSize(int width, int height)
+  {
+    _view_width = width;
+    _view_height = height < 0 ? width : height;
 
-  _use_image_coords = use;
+    if( camera )
+      updateCoordinateFrame();
+  }
 
-  if( texture )
-    updateCoordinateFrame();
-}
+  //----------------------------------------------------------------------------
+  void ODGauge::useImageCoords(bool use)
+  {
+    if( use == _use_image_coords )
+      return;
 
-//------------------------------------------------------------------------------
-void ODGauge::useStencil(bool use)
-{
-  if( use == _use_stencil )
-    return;
+    _use_image_coords = use;
 
-  _use_stencil = use;
+    if( texture )
+      updateCoordinateFrame();
+  }
 
-  if( texture )
-    updateStencil();
-}
+  //----------------------------------------------------------------------------
+  void ODGauge::useStencil(bool use)
+  {
+    if( use == _use_stencil )
+      return;
 
-//------------------------------------------------------------------------------
-void ODGauge::setSampling( bool mipmapping,
-                             int coverage_samples,
-                             int color_samples )
-{
-  if(    _use_mipmapping == mipmapping
-      && _coverage_samples == coverage_samples
-      && _color_samples == color_samples )
-    return;
+    _use_stencil = use;
 
-  _use_mipmapping = mipmapping;
+    if( texture )
+      updateStencil();
+  }
 
-  if( color_samples > coverage_samples )
+  //----------------------------------------------------------------------------
+  void ODGauge::setSampling( bool mipmapping,
+                               int coverage_samples,
+                               int color_samples )
   {
-    SG_LOG
-    (
-      SG_GL,
-      SG_WARN,
-      "ODGauge::setSampling: color_samples > coverage_samples not allowed!"
-    );
-    color_samples = coverage_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,
+        "ODGauge::setSampling: color_samples > coverage_samples not allowed!"
+      );
+      color_samples = coverage_samples;
+    }
+
+    _coverage_samples = coverage_samples;
+    _color_samples = color_samples;
+
+    updateSampling();
   }
 
-  _coverage_samples = coverage_samples;
-  _color_samples = color_samples;
-
-  updateSampling();
-}
-
-//------------------------------------------------------------------------------
-void ODGauge::setRender(bool render)
-{
-  // Only the far camera should trigger this texture to be rendered.
-  camera->setNodeMask(render ? simgear::BACKGROUND_BIT : 0);
-}
-
-//------------------------------------------------------------------------------
-bool ODGauge::serviceable(void)
-{
-  return rtAvailable;
-}
-
-//------------------------------------------------------------------------------
-void ODGauge::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 )
+  //----------------------------------------------------------------------------
+  void ODGauge::setRender(bool render)
   {
-    texture = new osg::Texture2D;
-    texture->setTextureSize(_size_x, _size_y);
-    texture->setInternalFormat(GL_RGBA);
+    // Only the far camera should trigger this texture to be rendered.
+    camera->setNodeMask(render ? simgear::BACKGROUND_BIT : 0);
   }
 
-  updateSampling();
-
-  _cb_cam_add(camera.get());
-  rtAvailable = true;
-}
-
-//------------------------------------------------------------------------------
-void ODGauge::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. )
-    );
-}
+  //----------------------------------------------------------------------------
+  bool ODGauge::serviceable(void)
+  {
+    return rtAvailable;
+  }
 
-//------------------------------------------------------------------------------
-void ODGauge::updateStencil()
-{
-  assert( camera );
+  //----------------------------------------------------------------------------
+  void ODGauge::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();
 
-  GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
+    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();
+
+    if( _system_adapter )
+      _system_adapter->addCamera(camera.get());
+
+    rtAvailable = true;
+  }
 
-  if( _use_stencil)
+  //----------------------------------------------------------------------------
+  void ODGauge::updateCoordinateFrame()
   {
-    camera->attach( osg::Camera::PACKED_DEPTH_STENCIL_BUFFER,
-                     GL_DEPTH_STENCIL_EXT );
-    mask |= GL_STENCIL_BUFFER_BIT;
+    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. )
+      );
   }
-  else
+
+  //----------------------------------------------------------------------------
+  void ODGauge::updateStencil()
   {
-    camera->detach(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER);
+    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);
   }
 
-  camera->setClearMask(mask);
-}
+  //----------------------------------------------------------------------------
+  void ODGauge::updateSampling()
+  {
+    assert( camera );
+    assert( texture );
 
-//------------------------------------------------------------------------------
-void ODGauge::updateSampling()
-{
-  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
-  );
-}
+    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
+    );
+  }
 
+} // namespace canvas
 } // namespace simgear