OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
WGETextureHud.cpp
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
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     // cleanup
00059 }
00060 
00061 void WGETextureHud::SafeUpdateCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
00062 {
00063     // set the new size of the widget (how can we get this data?)
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     // border around each element
00069     unsigned int border = 5;
00070 
00071     // update all those
00072     osg::Group* group = static_cast< osg::Group* >( node );
00073 
00074     unsigned int nextX = border;
00075     unsigned int nextY = border;
00076 
00077     // iterate all children
00078     for( size_t i = 0; i < group->getNumChildren(); ++i )
00079     {
00080         // all children are WGETextureHudEntries.
00081         WGETextureHudEntry* tex = static_cast< WGETextureHudEntry* >( group->getChild( i ) );
00082 
00083         // scale the height of the quad (texture) to have proper aspect ratio
00084         float height = static_cast< float >( m_hud->getMaxElementWidth() * tex->getRealHeight() ) / static_cast< float >( tex->getRealWidth() );
00085 
00086         // scale texture if needed
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             // this also changes the aspect ratio in the texture:
00094             height = static_cast< float >( m_hud->getMaxElementWidth() * screenHeight ) / static_cast< float >( screenWidth );
00095         }
00096 
00097         // scale them to their final size
00098         osg::Matrixd scale = osg::Matrixd::scale( m_hud->getMaxElementWidth(), height, 1.0 );
00099 
00100         // need to add a "line-break"?
00101         if( nextY + height + border > screenHeight )
00102         {
00103             nextX += m_hud->getMaxElementWidth() + border;
00104             nextY = border;
00105         }
00106 
00107         // transform them to the right place
00108         osg::Matrixd translate = osg::Matrixd::translate( static_cast< double >( nextX ), static_cast< double >( nextY ), 0.0 );
00109         tex->setMatrix( scale * translate );
00110 
00111         // calculate the y position of the next texture
00112         nextY += height + border;
00113     }
00114 
00115     // update all the others
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  * This method compares a specified texture with the specified node. If the node is an WGETextureHudEntry instance, the containied textures
00131  * get compared.
00132  *
00133  * \param tex the texture to compare to
00134  * \param node the node
00135  *
00136  * \return true if node->m_texture == tex.
00137  */
00138 bool hudEntryPredicate( osg::ref_ptr< osg::Texture > tex, osg::ref_ptr< osg::Node > const& node )
00139 {
00140     // is the node an WGETextureHudEntry?
00141     WGETextureHud::WGETextureHudEntry const* e = dynamic_cast< WGETextureHud::WGETextureHudEntry const* >( node.get() );
00142     if( !e )
00143     {
00144         return false;
00145     }
00146 
00147     // check if textures are equal
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;  // NOLINT - if the
00155     // space after bool is removed (as the stylechecker want) it interprets it as old-style cast and complains about it. This is valid syntax for
00156     // boost::function.
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     // Texture Quad
00185 
00186     osg::Geode* geode = new osg::Geode();
00187 
00188     // Set up geometry for the HUD and add it to the HUD
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     // Create and set up a state set using the texture from above
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     // enable texture coordinate manipulation via texture matrices
00232     m_texMat = new osg::TexMat;
00233     m_texMat->setMatrix( osg::Matrixd::identity() );
00234     state->setTextureAttributeAndModes( 0, m_texMat, osg::StateAttribute::ON );
00235 
00236     // This disables colorblending of the texture with the underlying quad
00237     // osg::TexEnv* decalState = new osg::TexEnv();
00238     // decalState->setMode( osg::TexEnv::DECAL );
00239     // state->setTextureAttribute( 0, decalState, osg::StateAttribute::ON );
00240 
00241     // en/disable blending
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     // add the geode
00255     addChild( geode );
00256 
00257     //////////////////////////////////////////////////
00258     // Text
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     // cleanup
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 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends