#endif
#include "ODGauge.hxx"
+#include "Canvas.hxx"
#include "CanvasSystemAdapter.hxx"
#include <simgear/debug/logstream.hxx>
#include <osg/ShadeModel>
#include <osg/StateSet>
#include <osg/FrameBufferObject> // for GL_DEPTH_STENCIL_EXT on Windows
+#include <osg/Version>
+#include <osgUtil/RenderBin>
#include <cassert>
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<const PreOrderBin*>(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 )
{
}
clear();
}
- //----------------------------------------------------------------------------
- void ODGauge::setSystemAdapter(const SystemAdapterPtr& system_adapter)
- {
- _system_adapter = system_adapter;
- }
-
//----------------------------------------------------------------------------
void ODGauge::setSize(int size_x, int size_y)
{
}
//----------------------------------------------------------------------------
- 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
}
//----------------------------------------------------------------------------
- bool ODGauge::serviceable(void)
+ bool ODGauge::serviceable() const
{
- return rtAvailable;
+ return _flags & AVAILABLE;
}
//----------------------------------------------------------------------------
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;
}
//----------------------------------------------------------------------------
void ODGauge::reinit()
{
- osg::NodeCallback* cull_callback = camera ? camera->getCullCallback() : 0;
+ osg::NodeCallback* cull_callback =
+ camera
+#if OSG_VERSION_LESS_THAN(3,3,2)
+ ? camera->getCullCallback()
+#else
+ ? dynamic_cast<osg::NodeCallback*>(camera->getCullCallback())
+#endif
+ : 0;
+
clear();
allocRT(cull_callback);
}
//----------------------------------------------------------------------------
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;
}
//----------------------------------------------------------------------------
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)
);
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 );
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