~ubuntu-branches/ubuntu/precise/openwalnut/precise

« back to all changes in this revision

Viewing changes to src/core/graphicsEngine/WGETextureHud.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Eichelbaum
  • Date: 2011-06-21 10:26:54 UTC
  • Revision ID: james.westby@ubuntu.com-20110621102654-rq0zf436q949biih
Tags: upstream-1.2.5
ImportĀ upstreamĀ versionĀ 1.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
43
WGETextureHud::WGETextureHud():
 
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
 
 
56
WGETextureHud::~WGETextureHud()
 
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
 
87
        if( m_hud->m_coupleTexViewport )
 
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
{
 
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
 
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
 
 
170
void WGETextureHud::coupleViewportWithTextureViewport( bool couple )
 
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
 
 
274
WGETextureHud::WGETextureHudEntry::~WGETextureHudEntry()
 
275
{
 
276
    // cleanup
 
277
}
 
278
 
 
279
unsigned int WGETextureHud::WGETextureHudEntry::getRealWidth() const
 
280
{
 
281
    return m_texture->getTextureWidth();
 
282
}
 
283
 
 
284
unsigned int WGETextureHud::WGETextureHudEntry::getRealHeight() const
 
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
 
 
294
std::string WGETextureHud::WGETextureHudEntry::getName() const
 
295
{
 
296
    return m_name;
 
297
}
 
298
 
 
299
unsigned int WGETextureHud::getMaxElementWidth() const
 
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
 
 
314
size_t WGETextureHud::getRenderBin() const
 
315
{
 
316
    return m_renderBin;
 
317
}
 
318