]> git.mxchange.org Git - simgear.git/commitdiff
Move FGODGauge from FlightGear to SimGear.
authorThomas Geymayer <tomgey@gmail.com>
Fri, 19 Oct 2012 09:48:39 +0000 (11:48 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Fri, 19 Oct 2012 09:56:32 +0000 (11:56 +0200)
This is a first step for moving the Canvas system to SimGear to
make it accessible to other applications (eg.FGRadar is going to
use it)

simgear/CMakeLists.txt
simgear/canvas/CMakeLists.txt [new file with mode: 0644]
simgear/canvas/ODGauge.cxx [new file with mode: 0644]
simgear/canvas/ODGauge.hxx [new file with mode: 0644]

index 3885643447874107f356cc080c51f2fdb6e6621b..fd83c895e50e6130d24203ea0efe6314000c1492 100644 (file)
@@ -24,6 +24,7 @@ foreach( mylibfolder
 endforeach( mylibfolder )
 
 if(NOT SIMGEAR_HEADLESS)
+    add_subdirectory(canvas)
     add_subdirectory(environment)
     add_subdirectory(screen)
     add_subdirectory(scene)
diff --git a/simgear/canvas/CMakeLists.txt b/simgear/canvas/CMakeLists.txt
new file mode 100644 (file)
index 0000000..430c482
--- /dev/null
@@ -0,0 +1,11 @@
+include (SimGearComponent)
+
+set(HEADERS
+    ODGauge.hxx
+    )
+
+set(SOURCES
+    ODGauge.cxx
+    )
+
+simgear_scene_component(canvas canvas "${SOURCES}" "${HEADERS}")
diff --git a/simgear/canvas/ODGauge.cxx b/simgear/canvas/ODGauge.cxx
new file mode 100644 (file)
index 0000000..d0c5e2c
--- /dev/null
@@ -0,0 +1,276 @@
+// Owner Drawn Gauge helper class
+//
+// Written by Harald JOHNSEN, started May 2005.
+//
+// Copyright (C) 2005  Harald JOHNSEN
+//
+// Ported to OSG by Tim Moore - Jun 2007
+//
+// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012
+// 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 program 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.
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#  include <simgear_config.h>
+#endif
+
+#include <osg/Texture2D>
+#include <osg/AlphaFunc>
+#include <osg/BlendFunc>
+#include <osg/Camera>
+#include <osg/Matrix>
+#include <osg/PolygonMode>
+#include <osg/ShadeModel>
+#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 )
+{
+
+}
+
+//------------------------------------------------------------------------------
+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;
+
+  if( texture.valid() )
+    texture->setTextureSize(_size_x, _size_x);
+}
+
+//----------------------------------------------------------------------------
+void ODGauge::setViewSize(int width, int height)
+{
+  _view_width = width;
+  _view_height = height < 0 ? width : height;
+
+  if( camera )
+    updateCoordinateFrame();
+}
+
+//------------------------------------------------------------------------------
+void ODGauge::useImageCoords(bool use)
+{
+  if( use == _use_image_coords )
+    return;
+
+  _use_image_coords = use;
+
+  if( texture )
+    updateCoordinateFrame();
+}
+
+//------------------------------------------------------------------------------
+void ODGauge::useStencil(bool use)
+{
+  if( use == _use_stencil )
+    return;
+
+  _use_stencil = use;
+
+  if( texture )
+    updateStencil();
+}
+
+//------------------------------------------------------------------------------
+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_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();
+}
+
+//------------------------------------------------------------------------------
+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 )
+  {
+    texture = new osg::Texture2D;
+    texture->setTextureSize(_size_x, _size_y);
+    texture->setInternalFormat(GL_RGBA);
+  }
+
+  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. )
+    );
+}
+
+//------------------------------------------------------------------------------
+void ODGauge::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 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
+  );
+}
+
+} // namespace simgear
diff --git a/simgear/canvas/ODGauge.hxx b/simgear/canvas/ODGauge.hxx
new file mode 100644 (file)
index 0000000..64efa84
--- /dev/null
@@ -0,0 +1,156 @@
+// Owner Drawn Gauge helper class
+//
+// Written by Harald JOHNSEN, started May 2005.
+//
+// Copyright (C) 2005  Harald JOHNSEN - hjohnsen@evc.net
+//
+// Ported to OSG by Tim Moore - Jun 2007
+//
+// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012
+// 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 program 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.
+//
+//
+
+#ifndef _SG_OD_GAUGE_HXX
+#define _SG_OD_GAUGE_HXX
+
+#include <osg/NodeCallback>
+#include <osg/Group>
+
+#include <boost/function.hpp>
+
+namespace osg
+{
+  class Camera;
+  class Texture2D;
+}
+
+namespace simgear
+{
+  /**
+   * Owner Drawn Gauge (aka render-to-texture) helper class
+   */
+  class ODGauge
+  {
+    public:
+
+      typedef boost::function<void(osg::Camera*)> CameraRegistrationCallback;
+
+      ODGauge( const CameraRegistrationCallback& cb_camera_add,
+               const CameraRegistrationCallback& cb_camera_remove );
+      virtual ~ODGauge();
+
+      /**
+       * Set the size of the render target.
+       *
+       * @param size_x    X size
+       * @param size_y    Y size. Defaults to size_x if not specified
+       */
+      void setSize(int size_x, int size_y = -1);
+
+      /**
+       * Set the size of the viewport
+       *
+       * @param width
+       * @param height    Defaults to width if not specified
+       */
+      void setViewSize(int width, int height = -1);
+
+      /**
+       * DEPRECATED
+       *
+       * Get size of squared texture
+       */
+      int size() const { return _size_x; }
+
+      /**
+       * Set whether to use image coordinates or not.
+       *
+       * Default: origin == center of texture
+       * Image Coords: origin == top left corner
+       */
+      void useImageCoords(bool use = true);
+
+      /**
+       * Enable/Disable using a stencil buffer
+       */
+      void useStencil(bool use = true);
+
+      /**
+       * Set sampling parameters for mipmapping and coverage sampling
+       * antialiasing.
+       *
+       * @note color_samples is not allowed to be higher than coverage_samples
+       *
+       */
+      void setSampling( bool mipmapping,
+                        int coverage_samples = 0,
+                        int color_samples = 0 );
+
+      /**
+       * Enable/Disable updating the texture (If disabled the contents of the
+       * texture remains with the outcome of the last rendering pass)
+       */
+      void setRender(bool render);
+
+      /**
+       * Say if we can render to a texture.
+       * @return true if rtt is available
+       */
+      bool serviceable(void);
+
+      /**
+       * Get the OSG camera for drawing this gauge.
+       */
+      osg::Camera* getCamera() const { return camera.get(); }
+
+      osg::Texture2D* getTexture() const { return texture.get(); }
+
+      // Real initialization function. Bad name.
+      void allocRT(osg::NodeCallback* camera_cull_callback = 0);
+
+    private:
+
+      int _size_x,
+          _size_y,
+          _view_width,
+          _view_height;
+      bool _use_image_coords,
+           _use_stencil,
+           _use_mipmapping;
+
+      // Multisampling parameters
+      int  _coverage_samples,
+           _color_samples;
+
+      bool rtAvailable;
+      osg::ref_ptr<osg::Camera> camera;
+      osg::ref_ptr<osg::Texture2D> texture;
+
+      CameraRegistrationCallback _cb_cam_add,
+                                 _cb_cam_remove;
+
+      void updateCoordinateFrame();
+      void updateStencil();
+      void updateSampling();
+
+  };
+
+} // namespace simgear
+
+#endif // _SG_OD_GAUGE_HXX