X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fcanvas%2FODGauge.cxx;h=5c547eafa1af784ddc0cfffb46f278bad1cae190;hb=519326f7518b6e8760a53db6ebebd692655ef7be;hp=b59efc6a0f762d82608c687dca564fccfa97ce49;hpb=2263823f7574a86687994535a02b6a2376b843b5;p=simgear.git diff --git a/simgear/canvas/ODGauge.cxx b/simgear/canvas/ODGauge.cxx index b59efc6a..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 ) { } @@ -73,12 +124,6 @@ namespace canvas clear(); } - //---------------------------------------------------------------------------- - void ODGauge::setSystemAdapter(const SystemAdapterPtr& system_adapter) - { - _system_adapter = system_adapter; - } - //---------------------------------------------------------------------------- void ODGauge::setSize(int size_x, int size_y) { @@ -102,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 @@ -162,9 +208,9 @@ namespace canvas } //---------------------------------------------------------------------------- - bool ODGauge::serviceable(void) + bool ODGauge::serviceable() const { - return rtAvailable; + return _flags & AVAILABLE; } //---------------------------------------------------------------------------- @@ -196,26 +242,25 @@ 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( _system_adapter ) - _system_adapter->addCamera(camera.get()); + if( Canvas::getSystemAdapter() ) + Canvas::getSystemAdapter()->addCamera(camera.get()); - rtAvailable = true; + _flags |= AVAILABLE; } //---------------------------------------------------------------------------- @@ -229,12 +274,22 @@ namespace canvas //---------------------------------------------------------------------------- void ODGauge::clear() { - if( camera.valid() && _system_adapter ) - _system_adapter->removeCamera(camera.get()); + if( camera.valid() && Canvas::getSystemAdapter() ) + Canvas::getSystemAdapter()->removeCamera(camera.get()); camera.release(); texture.release(); - rtAvailable = false; + _flags &= ~AVAILABLE; + } + + //---------------------------------------------------------------------------- + bool ODGauge::updateFlag(Flags flag, bool enable) + { + if( bool(_flags & flag) == enable ) + return false; + + _flags ^= flag; + return true; } //---------------------------------------------------------------------------- @@ -249,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) ); @@ -267,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 ); @@ -289,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