00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <iostream>
00026 #include <string>
00027
00028 #include <boost/bind.hpp>
00029 #include <boost/function.hpp>
00030
00031 #include <osg/Camera>
00032 #include <osg/Geode>
00033 #include <osg/Geometry>
00034 #include <osg/MatrixTransform>
00035 #include <osg/Node>
00036 #include <osg/TexEnv>
00037 #include <osgText/Text>
00038
00039 #include "../common/WPathHelper.h"
00040
00041 #include "WGETextureHud.h"
00042
00043 WGETextureHud::WGETextureHud():
00044 osg::Projection(),
00045 m_group( new WGEGroupNode() ),
00046 m_maxElementWidth( 256 ),
00047 m_renderBin( 10000 ),
00048 m_viewport( new osg::Viewport() ),
00049 m_coupleTexViewport( false )
00050 {
00051 getOrCreateStateSet()->setRenderBinDetails( m_renderBin, "RenderBin" );
00052 m_group->addUpdateCallback( new SafeUpdateCallback( this ) );
00053 addChild( m_group );
00054 }
00055
00056 WGETextureHud::~WGETextureHud()
00057 {
00058
00059 }
00060
00061 void WGETextureHud::SafeUpdateCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
00062 {
00063
00064 unsigned int screenWidth = m_hud->m_viewport->width();
00065 unsigned int screenHeight = m_hud->m_viewport->height();
00066 m_hud->setMatrix( osg::Matrix::ortho2D( 0, screenWidth, 0, screenHeight ) );
00067
00068
00069 unsigned int border = 5;
00070
00071
00072 osg::Group* group = static_cast< osg::Group* >( node );
00073
00074 unsigned int nextX = border;
00075 unsigned int nextY = border;
00076
00077
00078 for( size_t i = 0; i < group->getNumChildren(); ++i )
00079 {
00080
00081 WGETextureHudEntry* tex = static_cast< WGETextureHudEntry* >( group->getChild( i ) );
00082
00083
00084 float height = static_cast< float >( m_hud->getMaxElementWidth() * tex->getRealHeight() ) / static_cast< float >( tex->getRealWidth() );
00085
00086
00087 if( m_hud->m_coupleTexViewport )
00088 {
00089 osg::ref_ptr< osg::TexMat > texMat = tex->getTextureMatrix();
00090 texMat->setMatrix( osg::Matrixd::scale( static_cast< float >( screenWidth ) / static_cast< float >( tex->getRealWidth() ),
00091 static_cast< float >( screenHeight )/ static_cast< float >( tex->getRealHeight() ), 1.0 ) );
00092
00093
00094 height = static_cast< float >( m_hud->getMaxElementWidth() * screenHeight ) / static_cast< float >( screenWidth );
00095 }
00096
00097
00098 osg::Matrixd scale = osg::Matrixd::scale( m_hud->getMaxElementWidth(), height, 1.0 );
00099
00100
00101 if( nextY + height + border > screenHeight )
00102 {
00103 nextX += m_hud->getMaxElementWidth() + border;
00104 nextY = border;
00105 }
00106
00107
00108 osg::Matrixd translate = osg::Matrixd::translate( static_cast< double >( nextX ), static_cast< double >( nextY ), 0.0 );
00109 tex->setMatrix( scale * translate );
00110
00111
00112 nextY += height + border;
00113 }
00114
00115
00116 traverse( node, nv );
00117 }
00118
00119 void WGETextureHud::addTexture( osg::ref_ptr< WGETextureHudEntry > texture )
00120 {
00121 m_group->insert( texture );
00122 }
00123
00124 void WGETextureHud::removeTexture( osg::ref_ptr< WGETextureHudEntry > texture )
00125 {
00126 m_group->remove( texture );
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 bool hudEntryPredicate( osg::ref_ptr< osg::Texture > tex, osg::ref_ptr< osg::Node > const& node )
00139 {
00140
00141 WGETextureHud::WGETextureHudEntry const* e = dynamic_cast< WGETextureHud::WGETextureHudEntry const* >( node.get() );
00142 if( !e )
00143 {
00144 return false;
00145 }
00146
00147
00148 return e->getTexture() == tex;
00149 }
00150
00151 void WGETextureHud::removeTexture( osg::ref_ptr< osg::Texture > texture )
00152 {
00153 typedef WPredicateHelper::ArbitraryPredicate< osg::ref_ptr< osg::Node > const,
00154 boost::function< bool ( osg::ref_ptr< osg::Node > const& ) > > TexCheck;
00155
00156
00157
00158 m_group->remove_if(
00159 boost::shared_ptr< WGEGroupNode::NodePredicate >(
00160 new TexCheck( boost::bind( &hudEntryPredicate, texture, _1 ) )
00161 )
00162 );
00163 }
00164
00165 void WGETextureHud::setViewport( osg::Viewport* viewport )
00166 {
00167 m_viewport = viewport;
00168 }
00169
00170 void WGETextureHud::coupleViewportWithTextureViewport( bool couple )
00171 {
00172 m_coupleTexViewport = couple;
00173 }
00174
00175 WGETextureHud::WGETextureHudEntry::WGETextureHudEntry( osg::ref_ptr< osg::Texture2D > texture, std::string name, bool transparency ):
00176 osg::MatrixTransform(),
00177 m_texture( texture ),
00178 m_name( name )
00179 {
00180 setMatrix( osg::Matrixd::identity() );
00181 setReferenceFrame( osg::Transform::ABSOLUTE_RF );
00182
00183
00184
00185
00186 osg::Geode* geode = new osg::Geode();
00187
00188
00189 osg::ref_ptr< osg::Geometry > HUDBackgroundGeometry = new osg::Geometry();
00190
00191 osg::ref_ptr< osg::Vec3Array > HUDBackgroundVertices = new osg::Vec3Array;
00192 HUDBackgroundVertices->push_back( osg::Vec3( 0, 0, -1 ) );
00193 HUDBackgroundVertices->push_back( osg::Vec3( 1, 0, -1 ) );
00194 HUDBackgroundVertices->push_back( osg::Vec3( 1, 1, -1 ) );
00195 HUDBackgroundVertices->push_back( osg::Vec3( 0, 1, -1 ) );
00196
00197 osg::ref_ptr< osg::Vec3Array > HUDBackgroundTex = new osg::Vec3Array;
00198 HUDBackgroundTex->push_back( osg::Vec3( 0, 0, 0 ) );
00199 HUDBackgroundTex->push_back( osg::Vec3( 1, 0, 0 ) );
00200 HUDBackgroundTex->push_back( osg::Vec3( 1, 1, 0 ) );
00201 HUDBackgroundTex->push_back( osg::Vec3( 0, 1, 0 ) );
00202
00203 osg::ref_ptr< osg::DrawElementsUInt > HUDBackgroundIndices = new osg::DrawElementsUInt( osg::PrimitiveSet::POLYGON, 0 );
00204 HUDBackgroundIndices->push_back( 0 );
00205 HUDBackgroundIndices->push_back( 1 );
00206 HUDBackgroundIndices->push_back( 2 );
00207 HUDBackgroundIndices->push_back( 3 );
00208
00209 osg::ref_ptr< osg::Vec4Array > HUDcolors = new osg::Vec4Array;
00210 HUDcolors->push_back( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
00211
00212 osg::ref_ptr< osg::Vec3Array > HUDnormals = new osg::Vec3Array;
00213 HUDnormals->push_back( osg::Vec3( 0.0f, 0.0f, 1.0f ) );
00214 HUDBackgroundGeometry->setNormalArray( HUDnormals );
00215 HUDBackgroundGeometry->setNormalBinding( osg::Geometry::BIND_OVERALL );
00216 HUDBackgroundGeometry->addPrimitiveSet( HUDBackgroundIndices );
00217 HUDBackgroundGeometry->setVertexArray( HUDBackgroundVertices );
00218 HUDBackgroundGeometry->setColorArray( HUDcolors );
00219 HUDBackgroundGeometry->setTexCoordArray( 0, HUDBackgroundTex );
00220 HUDBackgroundGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
00221
00222 geode->addDrawable( HUDBackgroundGeometry );
00223
00224
00225 osg::StateSet* state = geode->getOrCreateStateSet();
00226 state->setTextureAttributeAndModes( 0, texture, osg::StateAttribute::ON );
00227 state->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
00228 state->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED );
00229 state->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00230
00231
00232 m_texMat = new osg::TexMat;
00233 m_texMat->setMatrix( osg::Matrixd::identity() );
00234 state->setTextureAttributeAndModes( 0, m_texMat, osg::StateAttribute::ON );
00235
00236
00237
00238
00239
00240
00241
00242 if( !transparency )
00243 {
00244 state->setMode( GL_BLEND, osg::StateAttribute::PROTECTED );
00245 state->setMode( GL_BLEND, osg::StateAttribute::OFF );
00246 }
00247 else
00248 {
00249 state->setMode( GL_BLEND, osg::StateAttribute::PROTECTED );
00250 state->setMode( GL_BLEND, osg::StateAttribute::ON );
00251 state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
00252 }
00253
00254
00255 addChild( geode );
00256
00257
00258
00259 osg::ref_ptr< osg::Geode > textGeode = new osg::Geode();
00260 state = textGeode->getOrCreateStateSet();
00261 state->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
00262 addChild( textGeode );
00263 osgText::Text* label = new osgText::Text();
00264 label->setFont( WPathHelper::getAllFonts().Default.file_string() );
00265 label->setBackdropType( osgText::Text::OUTLINE );
00266 label->setCharacterSize( 15 );
00267 label->setText( m_name );
00268 label->setAxisAlignment( osgText::Text::SCREEN );
00269 label->setPosition( osg::Vec3( 0.01, 0.01, -1.0 ) );
00270 label->setColor( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
00271 textGeode->addDrawable( label );
00272 }
00273
00274 WGETextureHud::WGETextureHudEntry::~WGETextureHudEntry()
00275 {
00276
00277 }
00278
00279 unsigned int WGETextureHud::WGETextureHudEntry::getRealWidth() const
00280 {
00281 return m_texture->getTextureWidth();
00282 }
00283
00284 unsigned int WGETextureHud::WGETextureHudEntry::getRealHeight() const
00285 {
00286 return m_texture->getTextureHeight();
00287 }
00288
00289 osg::ref_ptr< osg::TexMat > WGETextureHud::WGETextureHudEntry::getTextureMatrix() const
00290 {
00291 return m_texMat;
00292 }
00293
00294 std::string WGETextureHud::WGETextureHudEntry::getName() const
00295 {
00296 return m_name;
00297 }
00298
00299 unsigned int WGETextureHud::getMaxElementWidth() const
00300 {
00301 return m_maxElementWidth;
00302 }
00303
00304 void WGETextureHud::setMaxElementWidth( unsigned int width )
00305 {
00306 m_maxElementWidth = width;
00307 }
00308
00309 osg::ref_ptr< osg::Texture2D > WGETextureHud::WGETextureHudEntry::getTexture() const
00310 {
00311 return m_texture;
00312 }
00313
00314 size_t WGETextureHud::getRenderBin() const
00315 {
00316 return m_renderBin;
00317 }
00318