From: Thomas Geymayer Date: Fri, 19 Oct 2012 09:48:39 +0000 (+0200) Subject: Move FGODGauge from FlightGear to SimGear. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=f191b4f35c26d38cf856a9ea0e69706d2167396b;p=simgear.git Move FGODGauge from FlightGear to SimGear. 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) --- diff --git a/simgear/CMakeLists.txt b/simgear/CMakeLists.txt index 38856434..fd83c895 100644 --- a/simgear/CMakeLists.txt +++ b/simgear/CMakeLists.txt @@ -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 index 00000000..430c4825 --- /dev/null +++ b/simgear/canvas/CMakeLists.txt @@ -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 index 00000000..d0c5e2c9 --- /dev/null +++ b/simgear/canvas/ODGauge.cxx @@ -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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include // for GL_DEPTH_STENCIL_EXT on Windows + +#include +#include +#include "ODGauge.hxx" + +#include + +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 index 00000000..64efa84e --- /dev/null +++ b/simgear/canvas/ODGauge.hxx @@ -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 +#include + +#include + +namespace osg +{ + class Camera; + class Texture2D; +} + +namespace simgear +{ + /** + * Owner Drawn Gauge (aka render-to-texture) helper class + */ + class ODGauge + { + public: + + typedef boost::function 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 camera; + osg::ref_ptr texture; + + CameraRegistrationCallback _cb_cam_add, + _cb_cam_remove; + + void updateCoordinateFrame(); + void updateStencil(); + void updateSampling(); + + }; + +} // namespace simgear + +#endif // _SG_OD_GAUGE_HXX