OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WGETextureHud.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <iostream>
26 #include <string>
27 
28 #include <boost/bind.hpp>
29 #include <boost/function.hpp>
30 
31 #include <osg/Camera>
32 #include <osg/Geode>
33 #include <osg/Geometry>
34 #include <osg/MatrixTransform>
35 #include <osg/Node>
36 #include <osg/TexEnv>
37 #include <osgText/Text>
38 
39 #include "../common/WPathHelper.h"
40 
41 #include "WGETextureHud.h"
42 
44  osg::Projection(),
45  m_group( new WGEGroupNode() ),
46  m_maxElementWidth( 256 ),
47  m_renderBin( 10000 ),
48  m_viewport( new osg::Viewport() ),
49  m_coupleTexViewport( false )
50 {
51  getOrCreateStateSet()->setRenderBinDetails( m_renderBin, "RenderBin" );
52  m_group->addUpdateCallback( new SafeUpdateCallback( this ) );
53  addChild( m_group );
54 }
55 
57 {
58  // cleanup
59 }
60 
61 void WGETextureHud::SafeUpdateCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
62 {
63  // set the new size of the widget (how can we get this data?)
64  unsigned int screenWidth = m_hud->m_viewport->width();
65  unsigned int screenHeight = m_hud->m_viewport->height();
66  m_hud->setMatrix( osg::Matrix::ortho2D( 0, screenWidth, 0, screenHeight ) );
67 
68  // border around each element
69  unsigned int border = 5;
70 
71  // update all those
72  osg::Group* group = static_cast< osg::Group* >( node );
73 
74  unsigned int nextX = border;
75  unsigned int nextY = border;
76 
77  // iterate all children
78  for( size_t i = 0; i < group->getNumChildren(); ++i )
79  {
80  // all children are WGETextureHudEntries.
81  WGETextureHudEntry* tex = static_cast< WGETextureHudEntry* >( group->getChild( i ) );
82 
83  // scale the height of the quad (texture) to have proper aspect ratio
84  float height = static_cast< float >( m_hud->getMaxElementWidth() * tex->getRealHeight() ) / static_cast< float >( tex->getRealWidth() );
85 
86  // scale texture if needed
88  {
89  osg::ref_ptr< osg::TexMat > texMat = tex->getTextureMatrix();
90  texMat->setMatrix( osg::Matrixd::scale( static_cast< float >( screenWidth ) / static_cast< float >( tex->getRealWidth() ),
91  static_cast< float >( screenHeight )/ static_cast< float >( tex->getRealHeight() ), 1.0 ) );
92 
93  // this also changes the aspect ratio in the texture:
94  height = static_cast< float >( m_hud->getMaxElementWidth() * screenHeight ) / static_cast< float >( screenWidth );
95  }
96 
97  // scale them to their final size
98  osg::Matrixd scale = osg::Matrixd::scale( m_hud->getMaxElementWidth(), height, 1.0 );
99 
100  // need to add a "line-break"?
101  if( nextY + height + border > screenHeight )
102  {
103  nextX += m_hud->getMaxElementWidth() + border;
104  nextY = border;
105  }
106 
107  // transform them to the right place
108  osg::Matrixd translate = osg::Matrixd::translate( static_cast< double >( nextX ), static_cast< double >( nextY ), 0.0 );
109  tex->setMatrix( scale * translate );
110 
111  // calculate the y position of the next texture
112  nextY += height + border;
113  }
114 
115  // update all the others
116  traverse( node, nv );
117 }
118 
119 void WGETextureHud::addTexture( osg::ref_ptr< WGETextureHudEntry > texture )
120 {
121  m_group->insert( texture );
122 }
123 
124 void WGETextureHud::removeTexture( osg::ref_ptr< WGETextureHudEntry > texture )
125 {
126  m_group->remove( texture );
127 }
128 
129 /**
130  * This method compares a specified texture with the specified node. If the node is an WGETextureHudEntry instance, the containied textures
131  * get compared.
132  *
133  * \param tex the texture to compare to
134  * \param node the node
135  *
136  * \return true if node->m_texture == tex.
137  */
138 bool hudEntryPredicate( osg::ref_ptr< osg::Texture > tex, osg::ref_ptr< osg::Node > const& node )
139 {
140  // is the node an WGETextureHudEntry?
141  WGETextureHud::WGETextureHudEntry const* e = dynamic_cast< WGETextureHud::WGETextureHudEntry const* >( node.get() );
142  if( !e )
143  {
144  return false;
145  }
146 
147  // check if textures are equal
148  return e->getTexture() == tex;
149 }
150 
151 void WGETextureHud::removeTexture( osg::ref_ptr< osg::Texture > texture )
152 {
154  boost::function< bool ( osg::ref_ptr< osg::Node > const& ) > > TexCheck; // NOLINT - if the
155  // 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
156  // boost::function.
157 
158  m_group->remove_if(
159  boost::shared_ptr< WGEGroupNode::NodePredicate >(
160  new TexCheck( boost::bind( &hudEntryPredicate, texture, _1 ) )
161  )
162  );
163 }
164 
165 void WGETextureHud::setViewport( osg::Viewport* viewport )
166 {
167  m_viewport = viewport;
168 }
169 
171 {
172  m_coupleTexViewport = couple;
173 }
174 
175 WGETextureHud::WGETextureHudEntry::WGETextureHudEntry( osg::ref_ptr< osg::Texture2D > texture, std::string name, bool transparency ):
176  osg::MatrixTransform(),
177  m_texture( texture ),
178  m_name( name )
179 {
180  setMatrix( osg::Matrixd::identity() );
181  setReferenceFrame( osg::Transform::ABSOLUTE_RF );
182 
183  //////////////////////////////////////////////////
184  // Texture Quad
185 
186  osg::Geode* geode = new osg::Geode();
187 
188  // Set up geometry for the HUD and add it to the HUD
189  osg::ref_ptr< osg::Geometry > HUDBackgroundGeometry = new osg::Geometry();
190 
191  osg::ref_ptr< osg::Vec3Array > HUDBackgroundVertices = new osg::Vec3Array;
192  HUDBackgroundVertices->push_back( osg::Vec3( 0, 0, -1 ) );
193  HUDBackgroundVertices->push_back( osg::Vec3( 1, 0, -1 ) );
194  HUDBackgroundVertices->push_back( osg::Vec3( 1, 1, -1 ) );
195  HUDBackgroundVertices->push_back( osg::Vec3( 0, 1, -1 ) );
196 
197  osg::ref_ptr< osg::Vec3Array > HUDBackgroundTex = new osg::Vec3Array;
198  HUDBackgroundTex->push_back( osg::Vec3( 0, 0, 0 ) );
199  HUDBackgroundTex->push_back( osg::Vec3( 1, 0, 0 ) );
200  HUDBackgroundTex->push_back( osg::Vec3( 1, 1, 0 ) );
201  HUDBackgroundTex->push_back( osg::Vec3( 0, 1, 0 ) );
202 
203  osg::ref_ptr< osg::DrawElementsUInt > HUDBackgroundIndices = new osg::DrawElementsUInt( osg::PrimitiveSet::POLYGON, 0 );
204  HUDBackgroundIndices->push_back( 0 );
205  HUDBackgroundIndices->push_back( 1 );
206  HUDBackgroundIndices->push_back( 2 );
207  HUDBackgroundIndices->push_back( 3 );
208 
209  osg::ref_ptr< osg::Vec4Array > HUDcolors = new osg::Vec4Array;
210  HUDcolors->push_back( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
211 
212  osg::ref_ptr< osg::Vec3Array > HUDnormals = new osg::Vec3Array;
213  HUDnormals->push_back( osg::Vec3( 0.0f, 0.0f, 1.0f ) );
214  HUDBackgroundGeometry->setNormalArray( HUDnormals );
215  HUDBackgroundGeometry->setNormalBinding( osg::Geometry::BIND_OVERALL );
216  HUDBackgroundGeometry->addPrimitiveSet( HUDBackgroundIndices );
217  HUDBackgroundGeometry->setVertexArray( HUDBackgroundVertices );
218  HUDBackgroundGeometry->setColorArray( HUDcolors );
219  HUDBackgroundGeometry->setTexCoordArray( 0, HUDBackgroundTex );
220  HUDBackgroundGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
221 
222  geode->addDrawable( HUDBackgroundGeometry );
223 
224  // Create and set up a state set using the texture from above
225  osg::StateSet* state = geode->getOrCreateStateSet();
226  state->setTextureAttributeAndModes( 0, texture, osg::StateAttribute::ON );
227  state->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
228  state->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED );
229  state->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
230 
231  // enable texture coordinate manipulation via texture matrices
232  m_texMat = new osg::TexMat;
233  m_texMat->setMatrix( osg::Matrixd::identity() );
234  state->setTextureAttributeAndModes( 0, m_texMat, osg::StateAttribute::ON );
235 
236  // This disables colorblending of the texture with the underlying quad
237  // osg::TexEnv* decalState = new osg::TexEnv();
238  // decalState->setMode( osg::TexEnv::DECAL );
239  // state->setTextureAttribute( 0, decalState, osg::StateAttribute::ON );
240 
241  // en/disable blending
242  if( !transparency )
243  {
244  state->setMode( GL_BLEND, osg::StateAttribute::PROTECTED );
245  state->setMode( GL_BLEND, osg::StateAttribute::OFF );
246  }
247  else
248  {
249  state->setMode( GL_BLEND, osg::StateAttribute::PROTECTED );
250  state->setMode( GL_BLEND, osg::StateAttribute::ON );
251  state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
252  }
253 
254  // add the geode
255  addChild( geode );
256 
257  //////////////////////////////////////////////////
258  // Text
259  osg::ref_ptr< osg::Geode > textGeode = new osg::Geode();
260  state = textGeode->getOrCreateStateSet();
261  state->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
262  addChild( textGeode );
263  osgText::Text* label = new osgText::Text();
264  label->setFont( WPathHelper::getAllFonts().Default.file_string() );
265  label->setBackdropType( osgText::Text::OUTLINE );
266  label->setCharacterSize( 15 );
267  label->setText( m_name );
268  label->setAxisAlignment( osgText::Text::SCREEN );
269  label->setPosition( osg::Vec3( 0.01, 0.01, -1.0 ) );
270  label->setColor( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) );
271  textGeode->addDrawable( label );
272 }
273 
275 {
276  // cleanup
277 }
278 
280 {
281  return m_texture->getTextureWidth();
282 }
283 
285 {
286  return m_texture->getTextureHeight();
287 }
288 
289 osg::ref_ptr< osg::TexMat > WGETextureHud::WGETextureHudEntry::getTextureMatrix() const
290 {
291  return m_texMat;
292 }
293 
295 {
296  return m_name;
297 }
298 
300 {
301  return m_maxElementWidth;
302 }
303 
304 void WGETextureHud::setMaxElementWidth( unsigned int width )
305 {
306  m_maxElementWidth = width;
307 }
308 
309 osg::ref_ptr< osg::Texture2D > WGETextureHud::WGETextureHudEntry::getTexture() const
310 {
311  return m_texture;
312 }
313 
315 {
316  return m_renderBin;
317 }
318