// 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