X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fcanvas%2FODGauge.cxx;h=5c547eafa1af784ddc0cfffb46f278bad1cae190;hb=519326f7518b6e8760a53db6ebebd692655ef7be;hp=8b27c06f8727240d91db990a4173f874e1694697;hpb=b99f53fda3b06378668bdccd4a9d07161f263366;p=simgear.git diff --git a/simgear/canvas/ODGauge.cxx b/simgear/canvas/ODGauge.cxx index 8b27c06f..5c547eaf 100644 --- a/simgear/canvas/ODGauge.cxx +++ b/simgear/canvas/ODGauge.cxx @@ -29,6 +29,7 @@ #endif #include "ODGauge.hxx" +#include "Canvas.hxx" #include "CanvasSystemAdapter.hxx" #include @@ -43,6 +44,7 @@ #include #include #include // for GL_DEPTH_STENCIL_EXT on Windows +#include #include @@ -51,18 +53,67 @@ namespace simgear namespace canvas { + class PreOrderBin: + public osgUtil::RenderBin + { + public: + + PreOrderBin() + {} + PreOrderBin( const RenderBin& rhs, + const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY ): + RenderBin(rhs, copyop) + {} + + virtual osg::Object* cloneType() const + { + return new PreOrderBin(); + } + virtual osg::Object* clone(const osg::CopyOp& copyop) const + { + return new PreOrderBin(*this,copyop); + } + virtual bool isSameKindAs(const osg::Object* obj) const + { + return dynamic_cast(obj) != 0L; + } + virtual const char* className() const + { + return "PreOrderBin"; + } + + virtual void sort() + { + // Do not sort to keep traversal order... + } + }; + +#ifndef OSG_INIT_SINGLETON_PROXY + /** + * http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk/include/osg/Object + * + * Helper macro that creates a static proxy object to call singleton function + * on it's construction, ensuring that the singleton gets initialized at + * startup. + */ +# define OSG_INIT_SINGLETON_PROXY(ProxyName, Func)\ + static struct ProxyName{ ProxyName() { Func; } } s_##ProxyName; +#endif + + OSG_INIT_SINGLETON_PROXY( + PreOrderBinProxy, + (osgUtil::RenderBin::addRenderBinPrototype("PreOrderBin", new PreOrderBin)) + ); + //---------------------------------------------------------------------------- ODGauge::ODGauge(): _size_x( -1 ), _size_y( -1 ), _view_width( -1 ), _view_height( -1 ), - _use_image_coords( false ), - _use_stencil( false ), - _use_mipmapping( false ), + _flags(0), _coverage_samples( 0 ), - _color_samples( 0 ), - rtAvailable( false ) + _color_samples( 0 ) { } @@ -70,14 +121,7 @@ namespace canvas //---------------------------------------------------------------------------- ODGauge::~ODGauge() { - if( camera.valid() && _system_adapter ) - _system_adapter->removeCamera(camera.get()); - } - - //---------------------------------------------------------------------------- - void ODGauge::setSystemAdapter(const SystemAdapterPtr& system_adapter) - { - _system_adapter = system_adapter; + clear(); } //---------------------------------------------------------------------------- @@ -86,8 +130,10 @@ namespace canvas _size_x = size_x; _size_y = size_y < 0 ? size_x : size_y; - if( texture.valid() ) - texture->setTextureSize(_size_x, _size_x); + if( serviceable() ) + reinit(); + else if( texture ) + texture->setTextureSize(_size_x, _size_y); } //---------------------------------------------------------------------------- @@ -101,41 +147,42 @@ namespace canvas } //---------------------------------------------------------------------------- - void ODGauge::useImageCoords(bool use) + osg::Vec2s ODGauge::getViewSize() const { - if( use == _use_image_coords ) - return; - - _use_image_coords = use; + return osg::Vec2s(_view_width, _view_height); + } - if( texture ) + //---------------------------------------------------------------------------- + void ODGauge::useImageCoords(bool use) + { + if( updateFlag(USE_IMAGE_COORDS, use) && texture ) updateCoordinateFrame(); } //---------------------------------------------------------------------------- void ODGauge::useStencil(bool use) { - if( use == _use_stencil ) - return; - - _use_stencil = use; - - if( texture ) + if( updateFlag(USE_STENCIL, use) && texture ) updateStencil(); } + //---------------------------------------------------------------------------- + void ODGauge::useAdditiveBlend(bool use) + { + if( updateFlag(USE_ADDITIVE_BLEND, use) && camera ) + updateBlendMode(); + } + //---------------------------------------------------------------------------- void ODGauge::setSampling( bool mipmapping, - int coverage_samples, - int color_samples ) + int coverage_samples, + int color_samples ) { - if( _use_mipmapping == mipmapping + if( !updateFlag(USE_MIPMAPPING, mipmapping) && _coverage_samples == coverage_samples && _color_samples == color_samples ) return; - _use_mipmapping = mipmapping; - if( color_samples > coverage_samples ) { SG_LOG @@ -161,9 +208,9 @@ namespace canvas } //---------------------------------------------------------------------------- - bool ODGauge::serviceable(void) + bool ODGauge::serviceable() const { - return rtAvailable; + return _flags & AVAILABLE; } //---------------------------------------------------------------------------- @@ -195,26 +242,54 @@ namespace canvas osg::PolygonMode::FILL ), osg::StateAttribute::ON ); stateSet->setAttributeAndModes( - new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.0f), + new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.001f), 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->setResizeNonPowerOfTwoHint(false); texture->setTextureSize(_size_x, _size_y); texture->setInternalFormat(GL_RGBA); } updateSampling(); + updateBlendMode(); + + if( Canvas::getSystemAdapter() ) + Canvas::getSystemAdapter()->addCamera(camera.get()); + + _flags |= AVAILABLE; + } + + //---------------------------------------------------------------------------- + void ODGauge::reinit() + { + osg::NodeCallback* cull_callback = camera ? camera->getCullCallback() : 0; + clear(); + allocRT(cull_callback); + } + + //---------------------------------------------------------------------------- + void ODGauge::clear() + { + if( camera.valid() && Canvas::getSystemAdapter() ) + Canvas::getSystemAdapter()->removeCamera(camera.get()); + camera.release(); + texture.release(); - if( _system_adapter ) - _system_adapter->addCamera(camera.get()); + _flags &= ~AVAILABLE; + } + + //---------------------------------------------------------------------------- + bool ODGauge::updateFlag(Flags flag, bool enable) + { + if( bool(_flags & flag) == enable ) + return false; - rtAvailable = true; + _flags ^= flag; + return true; } //---------------------------------------------------------------------------- @@ -229,7 +304,7 @@ namespace canvas camera->setViewport(0, 0, _size_x, _size_y); - if( _use_image_coords ) + if( _flags & USE_IMAGE_COORDS ) camera->setProjectionMatrix( osg::Matrix::ortho2D(0, _view_width, _view_height, 0) ); @@ -247,7 +322,7 @@ namespace canvas GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; - if( _use_stencil) + if( _flags & USE_STENCIL ) { camera->attach( osg::Camera::PACKED_DEPTH_STENCIL_BUFFER, GL_DEPTH_STENCIL_EXT ); @@ -269,18 +344,36 @@ namespace canvas texture->setFilter( osg::Texture2D::MIN_FILTER, - _use_mipmapping ? osg::Texture2D::LINEAR_MIPMAP_LINEAR - : osg::Texture2D::LINEAR + (_flags & USE_MIPMAPPING) ? osg::Texture2D::LINEAR_MIPMAP_LINEAR + : osg::Texture2D::LINEAR ); camera->attach( osg::Camera::COLOR_BUFFER, texture.get(), 0, 0, - _use_mipmapping, + _flags & USE_MIPMAPPING, _coverage_samples, _color_samples ); } + //---------------------------------------------------------------------------- + void ODGauge::updateBlendMode() + { + assert( camera ); + + camera->getOrCreateStateSet() + ->setAttributeAndModes + ( + (_flags & USE_ADDITIVE_BLEND) + ? new osg::BlendFunc( osg::BlendFunc::SRC_ALPHA, + osg::BlendFunc::ONE_MINUS_SRC_ALPHA, + osg::BlendFunc::ONE, + osg::BlendFunc::ONE ) + : new osg::BlendFunc( osg::BlendFunc::SRC_ALPHA, + osg::BlendFunc::ONE_MINUS_SRC_ALPHA ) + ); + } + } // namespace canvas } // namespace simgear