X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=simgear%2Fcanvas%2FODGauge.cxx;h=8b27c06f8727240d91db990a4173f874e1694697;hb=b99f53fda3b06378668bdccd4a9d07161f263366;hp=d0c5e2c9556e2d7eef7d01d99aece680be5eaaa9;hpb=a7f64cf7aa9e3f379b718ff35a53b8884f171f52;p=simgear.git diff --git a/simgear/canvas/ODGauge.cxx b/simgear/canvas/ODGauge.cxx index d0c5e2c9..8b27c06f 100644 --- a/simgear/canvas/ODGauge.cxx +++ b/simgear/canvas/ODGauge.cxx @@ -10,26 +10,30 @@ // 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 #endif +#include "ODGauge.hxx" +#include "CanvasSystemAdapter.hxx" + +#include +#include + #include #include #include @@ -40,237 +44,243 @@ #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 ) +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