1
//---------------------------------------------------------------------------
3
// Project: OpenWalnut ( http://www.openwalnut.org )
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6
// For more information see http://www.openwalnut.org/copying
8
// This file is part of OpenWalnut.
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.
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.
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/>.
23
//---------------------------------------------------------------------------
28
#include <boost/bind.hpp>
29
#include <boost/function.hpp>
33
#include <osg/Geometry>
34
#include <osg/MatrixTransform>
37
#include <osgText/Text>
39
#include "../common/WPathHelper.h"
41
#include "WGETextureHud.h"
43
WGETextureHud::WGETextureHud():
45
m_group( new WGEGroupNode() ),
46
m_maxElementWidth( 256 ),
48
m_viewport( new osg::Viewport() ),
49
m_coupleTexViewport( false )
51
getOrCreateStateSet()->setRenderBinDetails( m_renderBin, "RenderBin" );
52
m_group->addUpdateCallback( new SafeUpdateCallback( this ) );
56
WGETextureHud::~WGETextureHud()
61
void WGETextureHud::SafeUpdateCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
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 ) );
68
// border around each element
69
unsigned int border = 5;
72
osg::Group* group = static_cast< osg::Group* >( node );
74
unsigned int nextX = border;
75
unsigned int nextY = border;
77
// iterate all children
78
for( size_t i = 0; i < group->getNumChildren(); ++i )
80
// all children are WGETextureHudEntries.
81
WGETextureHudEntry* tex = static_cast< WGETextureHudEntry* >( group->getChild( i ) );
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() );
86
// scale texture if needed
87
if( m_hud->m_coupleTexViewport )
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 ) );
93
// this also changes the aspect ratio in the texture:
94
height = static_cast< float >( m_hud->getMaxElementWidth() * screenHeight ) / static_cast< float >( screenWidth );
97
// scale them to their final size
98
osg::Matrixd scale = osg::Matrixd::scale( m_hud->getMaxElementWidth(), height, 1.0 );
100
// need to add a "line-break"?
101
if( nextY + height + border > screenHeight )
103
nextX += m_hud->getMaxElementWidth() + border;
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 );
111
// calculate the y position of the next texture
112
nextY += height + border;
115
// update all the others
116
traverse( node, nv );
119
void WGETextureHud::addTexture( osg::ref_ptr< WGETextureHudEntry > texture )
121
m_group->insert( texture );
124
void WGETextureHud::removeTexture( osg::ref_ptr< WGETextureHudEntry > texture )
126
m_group->remove( texture );
130
* This method compares a specified texture with the specified node. If the node is an WGETextureHudEntry instance, the containied textures
133
* \param tex the texture to compare to
134
* \param node the node
136
* \return true if node->m_texture == tex.
138
bool hudEntryPredicate( osg::ref_ptr< osg::Texture > tex, osg::ref_ptr< osg::Node > const& node )
140
// is the node an WGETextureHudEntry?
141
WGETextureHud::WGETextureHudEntry const* e = dynamic_cast< WGETextureHud::WGETextureHudEntry const* >( node.get() );
147
// check if textures are equal
148
return e->getTexture() == tex;
151
void WGETextureHud::removeTexture( osg::ref_ptr< osg::Texture > texture )
153
typedef WPredicateHelper::ArbitraryPredicate< osg::ref_ptr< osg::Node > const,
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
159
boost::shared_ptr< WGEGroupNode::NodePredicate >(
160
new TexCheck( boost::bind( &hudEntryPredicate, texture, _1 ) )
165
void WGETextureHud::setViewport( osg::Viewport* viewport )
167
m_viewport = viewport;
170
void WGETextureHud::coupleViewportWithTextureViewport( bool couple )
172
m_coupleTexViewport = couple;
175
WGETextureHud::WGETextureHudEntry::WGETextureHudEntry( osg::ref_ptr< osg::Texture2D > texture, std::string name, bool transparency ):
176
osg::MatrixTransform(),
177
m_texture( texture ),
180
setMatrix( osg::Matrixd::identity() );
181
setReferenceFrame( osg::Transform::ABSOLUTE_RF );
183
//////////////////////////////////////////////////
186
osg::Geode* geode = new osg::Geode();
188
// Set up geometry for the HUD and add it to the HUD
189
osg::ref_ptr< osg::Geometry > HUDBackgroundGeometry = new osg::Geometry();
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 ) );
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 ) );
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 );
209
osg::ref_ptr< osg::Vec4Array > HUDcolors = new osg::Vec4Array;
210
HUDcolors->push_back( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
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 );
222
geode->addDrawable( HUDBackgroundGeometry );
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 );
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 );
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 );
241
// en/disable blending
244
state->setMode( GL_BLEND, osg::StateAttribute::PROTECTED );
245
state->setMode( GL_BLEND, osg::StateAttribute::OFF );
249
state->setMode( GL_BLEND, osg::StateAttribute::PROTECTED );
250
state->setMode( GL_BLEND, osg::StateAttribute::ON );
251
state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
257
//////////////////////////////////////////////////
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 );
274
WGETextureHud::WGETextureHudEntry::~WGETextureHudEntry()
279
unsigned int WGETextureHud::WGETextureHudEntry::getRealWidth() const
281
return m_texture->getTextureWidth();
284
unsigned int WGETextureHud::WGETextureHudEntry::getRealHeight() const
286
return m_texture->getTextureHeight();
289
osg::ref_ptr< osg::TexMat > WGETextureHud::WGETextureHudEntry::getTextureMatrix() const
294
std::string WGETextureHud::WGETextureHudEntry::getName() const
299
unsigned int WGETextureHud::getMaxElementWidth() const
301
return m_maxElementWidth;
304
void WGETextureHud::setMaxElementWidth( unsigned int width )
306
m_maxElementWidth = width;
309
osg::ref_ptr< osg::Texture2D > WGETextureHud::WGETextureHudEntry::getTexture() const
314
size_t WGETextureHud::getRenderBin() const