root/OpenSceneGraph/trunk/examples/osgtexture2D/osgtexture2D.cpp @ 9636

Revision 9636, 24.1 kB (checked in by robert, 6 years ago)

Added setDataVariance(DYNAMIC) to text label as it's being updated dynamically

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgtexture2D.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osg/Node>
20#include <osg/Geometry>
21#include <osg/Notify>
22#include <osg/MatrixTransform>
23#include <osg/Texture2D>
24#include <osg/DrawPixels>
25#include <osg/PolygonOffset>
26#include <osg/Geode>
27
28#include <osgDB/Registry>
29#include <osgDB/ReadFile>
30
31#include <osgText/Text>
32
33#include <osgViewer/Viewer>
34
35///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36//
37// filter wall and animation callback.
38//
39
40class FilterCallback : public osg::NodeCallback
41{
42public:
43
44    FilterCallback(osg::Texture2D* texture,osgText::Text* text,double delay=1.0):
45        _texture(texture),
46        _text(text),
47        _delay(delay),
48        _currPos(0),
49        _prevTime(0.0)
50    {
51        // start with a mip mapped mode to ensure that
52        _minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_LINEAR);
53        _magFilterList.push_back(osg::Texture2D::LINEAR);
54        _textList.push_back("Tri-linear mip mapping (default filtering)\nsetFilter(MIN_FILTER,LINEAR_MIP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)");
55
56        _minFilterList.push_back(osg::Texture2D::NEAREST);
57        _magFilterList.push_back(osg::Texture2D::NEAREST);
58        _textList.push_back("Nearest filtering\nsetFilter(MIN_FILTER,NEAREST)\nsetFilter(MAG_FILTER,NEAREST)");
59       
60        _minFilterList.push_back(osg::Texture2D::LINEAR);
61        _magFilterList.push_back(osg::Texture2D::LINEAR);
62        _textList.push_back("Linear filtering\nsetFilter(MIN_FILTER,LINEAR)\nsetFilter(MAG_FILTER,LINEAR)");
63       
64        _minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_NEAREST);
65        _magFilterList.push_back(osg::Texture2D::LINEAR);
66        _textList.push_back("nearest mip mapping (default filtering)\nsetFilter(MIN_FILTER,)\nsetFilter(MAG_FILTER,LINEAR)");
67
68        _minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_NEAREST);
69        _magFilterList.push_back(osg::Texture2D::LINEAR);
70        _textList.push_back("bi-linear mip mapping\nsetFilter(MIN_FILTER,LINEAR_MIPMAP_NEAREST)\nsetFilter(MAG_FILTER,LINEAR)");
71
72        _minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_LINEAR);
73        _magFilterList.push_back(osg::Texture2D::LINEAR);
74        _textList.push_back("bi-linear mip mapping\nsetFilter(MIN_FILTER,NEAREST_MIPMAP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)");
75
76       
77        setValues();
78    }
79
80    virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
81    {
82        if (nv->getFrameStamp())
83        {
84            double currTime = nv->getFrameStamp()->getSimulationTime();
85            if (currTime-_prevTime>_delay)
86            {
87                // update filter modes and text.
88                setValues();
89               
90                // advance the current positon, wrap round if required.
91                _currPos++;
92                if (_currPos>=_minFilterList.size()) _currPos=0;                   
93               
94                // record time
95                _prevTime = currTime;
96            }
97        }
98    }
99   
100    void setValues()
101    {
102        _texture->setFilter(osg::Texture2D::MIN_FILTER,_minFilterList[_currPos]);
103        _texture->setFilter(osg::Texture2D::MAG_FILTER,_magFilterList[_currPos]);
104
105        _text->setText(_textList[_currPos]);
106    }
107
108protected:
109
110    typedef std::vector<osg::Texture2D::FilterMode> FilterList;
111    typedef std::vector<std::string>                TextList;
112
113    osg::ref_ptr<osg::Texture2D>    _texture;
114    osg::ref_ptr<osgText::Text>     _text;
115    double                          _delay;
116   
117    FilterList                      _minFilterList;
118    FilterList                      _magFilterList;
119    TextList                        _textList;
120   
121    unsigned int                    _currPos;
122    double                          _prevTime;
123   
124};
125
126osg::Node* createFilterWall(osg::BoundingBox& bb,const std::string& filename)
127{
128    osg::Group* group = new osg::Group;
129   
130    // left hand side of bounding box.
131    osg::Vec3 top_left(bb.xMin(),bb.yMin(),bb.zMax());
132    osg::Vec3 bottom_left(bb.xMin(),bb.yMin(),bb.zMin());
133    osg::Vec3 bottom_right(bb.xMin(),bb.yMax(),bb.zMin());
134    osg::Vec3 top_right(bb.xMin(),bb.yMax(),bb.zMax());
135    osg::Vec3 center(bb.xMin(),(bb.yMin()+bb.yMax())*0.5f,(bb.zMin()+bb.zMax())*0.5f);   
136    float height = bb.zMax()-bb.zMin();
137   
138    // create the geometry for the wall.
139    osg::Geometry* geom = new osg::Geometry;
140   
141    osg::Vec3Array* vertices = new osg::Vec3Array(4);
142    (*vertices)[0] = top_left;
143    (*vertices)[1] = bottom_left;
144    (*vertices)[2] = bottom_right;
145    (*vertices)[3] = top_right;
146    geom->setVertexArray(vertices);
147   
148    osg::Vec2Array* texcoords = new osg::Vec2Array(4);
149    (*texcoords)[0].set(0.0f,1.0f);
150    (*texcoords)[1].set(0.0f,0.0f);
151    (*texcoords)[2].set(1.0f,0.0f);
152    (*texcoords)[3].set(1.0f,1.0f);
153    geom->setTexCoordArray(0,texcoords);
154
155    osg::Vec3Array* normals = new osg::Vec3Array(1);
156    (*normals)[0].set(1.0f,0.0f,0.0f);
157    geom->setNormalArray(normals);
158    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
159   
160    osg::Vec4Array* colors = new osg::Vec4Array(1);
161    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
162    geom->setColorArray(colors);
163    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
164
165    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
166   
167    osg::Geode* geom_geode = new osg::Geode;
168    geom_geode->addDrawable(geom);
169    group->addChild(geom_geode);
170   
171   
172    // set up the texture state.   
173    osg::Texture2D* texture = new osg::Texture2D;
174    texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
175    texture->setImage(osgDB::readImageFile(filename));
176   
177    osg::StateSet* stateset = geom->getOrCreateStateSet();
178    stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
179   
180    // create the text label.
181   
182    osgText::Text* text = new osgText::Text;
183    text->setFont("fonts/arial.ttf");
184    text->setPosition(center);
185    text->setCharacterSize(height*0.03f);
186    text->setAlignment(osgText::Text::CENTER_CENTER);
187    text->setAxisAlignment(osgText::Text::YZ_PLANE);
188   
189    osg::Geode* text_geode = new osg::Geode;
190    text_geode->addDrawable(text);
191   
192    osg::StateSet* text_stateset = text_geode->getOrCreateStateSet();
193    text_stateset->setAttributeAndModes(new osg::PolygonOffset(-1.0f,-1.0f),osg::StateAttribute::ON);
194   
195    group->addChild(text_geode);
196
197    // set the update callback to cycle through the various min and mag filter modes.
198    group->setUpdateCallback(new FilterCallback(texture,text));
199   
200    return group;
201   
202}
203
204///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
205//
206// anisotropic wall and animation callback.
207//
208
209class AnisotropicCallback : public osg::NodeCallback
210{
211public:
212
213    AnisotropicCallback(osg::Texture2D* texture,osgText::Text* text,double delay=1.0):
214        _texture(texture),
215        _text(text),
216        _delay(delay),
217        _currPos(0),
218        _prevTime(0.0)
219    {
220
221        _maxAnisotropyList.push_back(1.0f);
222        _textList.push_back("No anisotropic filtering (default)\nsetMaxAnisotropy(1.0f)");
223       
224        _maxAnisotropyList.push_back(2.0f);
225        _textList.push_back("Anisotropic filtering\nsetMaxAnisotropy(2.0f)");
226       
227        _maxAnisotropyList.push_back(4.0f);
228        _textList.push_back("Anisotropic filtering\nsetMaxAnisotropy(4.0f)");
229       
230        _maxAnisotropyList.push_back(8.0f);
231        _textList.push_back("Anisotropic filtering\nsetMaxAnisotropy(8.0f)");
232       
233        _maxAnisotropyList.push_back(16.0f);
234        _textList.push_back("Higest quality anisotropic filtering\nsetMaxAnisotropy(16.0f)");
235
236        setValues();
237    }
238
239    virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
240    {
241        if (nv->getFrameStamp())
242        {
243            double currTime = nv->getFrameStamp()->getSimulationTime();
244            if (currTime-_prevTime>_delay)
245            {
246                // update filter modes and text.
247                setValues();
248               
249                // advance the current positon, wrap round if required.
250                _currPos++;
251                if (_currPos>=_maxAnisotropyList.size()) _currPos=0;                   
252               
253                // record time
254                _prevTime = currTime;
255            }
256        }
257    }
258   
259    void setValues()
260    {
261        _texture->setMaxAnisotropy(_maxAnisotropyList[_currPos]);
262
263        _text->setText(_textList[_currPos]);
264    }
265
266protected:
267
268    typedef std::vector<float>          AnisotropyList;
269    typedef std::vector<std::string>    TextList;
270
271    osg::ref_ptr<osg::Texture2D>    _texture;
272    osg::ref_ptr<osgText::Text>     _text;
273    double                          _delay;
274   
275    AnisotropyList                  _maxAnisotropyList;
276    TextList                        _textList;
277   
278    unsigned int                    _currPos;
279    double                          _prevTime;
280   
281};
282
283osg::Node* createAnisotripicWall(osg::BoundingBox& bb,const std::string& filename)
284{
285    osg::Group* group = new osg::Group;
286   
287    // left hand side of bounding box.
288    osg::Vec3 top_left(bb.xMin(),bb.yMax(),bb.zMin());
289    osg::Vec3 bottom_left(bb.xMin(),bb.yMin(),bb.zMin());
290    osg::Vec3 bottom_right(bb.xMax(),bb.yMin(),bb.zMin());
291    osg::Vec3 top_right(bb.xMax(),bb.yMax(),bb.zMin());
292    osg::Vec3 center((bb.xMin()+bb.xMax())*0.5f,(bb.yMin()+bb.yMax())*0.5f,bb.zMin());   
293    float height = bb.yMax()-bb.yMin();
294   
295    // create the geometry for the wall.
296    osg::Geometry* geom = new osg::Geometry;
297   
298    osg::Vec3Array* vertices = new osg::Vec3Array(4);
299    (*vertices)[0] = top_left;
300    (*vertices)[1] = bottom_left;
301    (*vertices)[2] = bottom_right;
302    (*vertices)[3] = top_right;
303    geom->setVertexArray(vertices);
304   
305    osg::Vec2Array* texcoords = new osg::Vec2Array(4);
306    (*texcoords)[0].set(0.0f,1.0f);
307    (*texcoords)[1].set(0.0f,0.0f);
308    (*texcoords)[2].set(1.0f,0.0f);
309    (*texcoords)[3].set(1.0f,1.0f);
310    geom->setTexCoordArray(0,texcoords);
311
312    osg::Vec3Array* normals = new osg::Vec3Array(1);
313    (*normals)[0].set(0.0f,0.0f,1.0f);
314    geom->setNormalArray(normals);
315    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
316   
317    osg::Vec4Array* colors = new osg::Vec4Array(1);
318    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
319    geom->setColorArray(colors);
320    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
321
322    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
323   
324    osg::Geode* geom_geode = new osg::Geode;
325    geom_geode->addDrawable(geom);
326    group->addChild(geom_geode);
327   
328   
329    // set up the texture state.   
330    osg::Texture2D* texture = new osg::Texture2D;
331    texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
332    texture->setImage(osgDB::readImageFile(filename));
333   
334    osg::StateSet* stateset = geom->getOrCreateStateSet();
335    stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
336   
337    // create the text label.
338   
339    osgText::Text* text = new osgText::Text;
340    text->setFont("fonts/arial.ttf");
341    text->setPosition(center);
342    text->setCharacterSize(height*0.03f);
343    text->setColor(osg::Vec4(1.0f,0.0f,1.0f,1.0f));
344    text->setAlignment(osgText::Text::CENTER_CENTER);
345    text->setAxisAlignment(osgText::Text::XY_PLANE);
346   
347    osg::Geode* text_geode = new osg::Geode;
348    text_geode->addDrawable(text);
349   
350    osg::StateSet* text_stateset = text_geode->getOrCreateStateSet();
351    text_stateset->setAttributeAndModes(new osg::PolygonOffset(-1.0f,-1.0f),osg::StateAttribute::ON);
352   
353    group->addChild(text_geode);
354
355    // set the update callback to cycle through the various min and mag filter modes.
356    group->setUpdateCallback(new AnisotropicCallback(texture,text));
357   
358    return group;
359   
360}
361
362///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
363//
364// wrap wall and animation callback.
365//
366class WrapCallback : public osg::NodeCallback
367{
368public:
369
370    WrapCallback(osg::Texture2D* texture,osgText::Text* text,double delay=1.0):
371        _texture(texture),
372        _text(text),
373        _delay(delay),
374        _currPos(0),
375        _prevTime(0.0)
376    {
377
378        _wrapList.push_back(osg::Texture2D::CLAMP);
379        _textList.push_back("Default tex coord clamp\nsetWrap(WRAP_S,CLAMP)");
380       
381        _wrapList.push_back(osg::Texture2D::CLAMP_TO_EDGE);
382        _textList.push_back("Clamp to edge extension\nsetWrap(WRAP_S,CLAMP_TO_EDGE)");
383       
384        _wrapList.push_back(osg::Texture2D::CLAMP_TO_BORDER);
385        _textList.push_back("Clamp to border color extension\nsetWrap(WRAP_S,CLAMP_TO_BORDER)");
386       
387        _wrapList.push_back(osg::Texture2D::REPEAT);
388        _textList.push_back("Repeat wrap\nsetWrap(WRAP_S,REPEAT)");
389       
390        _wrapList.push_back(osg::Texture2D::MIRROR);
391        _textList.push_back("Mirror wrap extension\nsetWrap(WRAP_S,MIRROR)");
392
393        setValues();
394    }
395
396    virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
397    {
398        if (nv->getFrameStamp())
399        {
400            double currTime = nv->getFrameStamp()->getSimulationTime();
401            if (currTime-_prevTime>_delay)
402            {
403                // update filter modes and text.
404                setValues();
405               
406                // advance the current positon, wrap round if required.
407                _currPos++;
408                if (_currPos>=_wrapList.size()) _currPos=0;                   
409               
410                // record time
411                _prevTime = currTime;
412            }
413        }
414    }
415   
416    void setValues()
417    {
418        _texture->setWrap(osg::Texture2D::WRAP_S,_wrapList[_currPos]);
419        _texture->setWrap(osg::Texture2D::WRAP_T,_wrapList[_currPos]);
420
421        _text->setText(_textList[_currPos]);
422    }
423
424protected:
425
426    typedef std::vector<osg::Texture2D::WrapMode> WrapList;
427    typedef std::vector<std::string>              TextList;
428
429    osg::ref_ptr<osg::Texture2D>    _texture;
430    osg::ref_ptr<osgText::Text>     _text;
431    double                          _delay;
432   
433    WrapList                        _wrapList;
434    TextList                        _textList;
435   
436    unsigned int                    _currPos;
437    double                          _prevTime;
438   
439};
440
441osg::Node* createWrapWall(osg::BoundingBox& bb,const std::string& filename)
442{
443    osg::Group* group = new osg::Group;
444   
445    // left hand side of bounding box.
446    osg::Vec3 top_left(bb.xMax(),bb.yMax(),bb.zMax());
447    osg::Vec3 bottom_left(bb.xMax(),bb.yMax(),bb.zMin());
448    osg::Vec3 bottom_right(bb.xMax(),bb.yMin(),bb.zMin());
449    osg::Vec3 top_right(bb.xMax(),bb.yMin(),bb.zMax());
450    osg::Vec3 center(bb.xMax(),(bb.yMin()+bb.yMax())*0.5f,(bb.zMin()+bb.zMax())*0.5f);   
451    float height = bb.zMax()-bb.zMin();
452   
453    // create the geometry for the wall.
454    osg::Geometry* geom = new osg::Geometry;
455   
456    osg::Vec3Array* vertices = new osg::Vec3Array(4);
457    (*vertices)[0] = top_left;
458    (*vertices)[1] = bottom_left;
459    (*vertices)[2] = bottom_right;
460    (*vertices)[3] = top_right;
461    geom->setVertexArray(vertices);
462   
463    osg::Vec2Array* texcoords = new osg::Vec2Array(4);
464    (*texcoords)[0].set(-1.0f,2.0f);
465    (*texcoords)[1].set(-1.0f,-1.0f);
466    (*texcoords)[2].set(2.0f,-1.0f);
467    (*texcoords)[3].set(2.0f,2.0f);
468    geom->setTexCoordArray(0,texcoords);
469
470    osg::Vec3Array* normals = new osg::Vec3Array(1);
471    (*normals)[0].set(-1.0f,0.0f,0.0f);
472    geom->setNormalArray(normals);
473    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
474   
475    osg::Vec4Array* colors = new osg::Vec4Array(1);
476    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
477    geom->setColorArray(colors);
478    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
479
480    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
481   
482    osg::Geode* geom_geode = new osg::Geode;
483    geom_geode->addDrawable(geom);
484    group->addChild(geom_geode);
485   
486   
487    // set up the texture state.   
488    osg::Texture2D* texture = new osg::Texture2D;
489    texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
490    texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,0.5f)); // only used when wrap is set to CLAMP_TO_BORDER
491    texture->setImage(osgDB::readImageFile(filename));
492   
493    osg::StateSet* stateset = geom->getOrCreateStateSet();
494    stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
495    stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
496    stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
497   
498    // create the text label.
499   
500    osgText::Text* text = new osgText::Text;
501    text->setFont("fonts/arial.ttf");
502    text->setPosition(center);
503    text->setCharacterSize(height*0.03f);
504    text->setAlignment(osgText::Text::CENTER_CENTER);
505    text->setAxisAlignment(osgText::Text::YZ_PLANE);
506   
507    osg::Geode* text_geode = new osg::Geode;
508    text_geode->addDrawable(text);
509   
510    osg::StateSet* text_stateset = text_geode->getOrCreateStateSet();
511    text_stateset->setAttributeAndModes(new osg::PolygonOffset(-1.0f,-1.0f),osg::StateAttribute::ON);
512   
513    group->addChild(text_geode);
514
515    // set the update callback to cycle through the various min and mag filter modes.
516    group->setUpdateCallback(new WrapCallback(texture,text));
517   
518    return group;
519   
520}
521
522///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
523//
524// sublooad wall and animation callback.
525//
526
527class ImageUpdateCallback : public osg::NodeCallback
528{
529public:
530
531    ImageUpdateCallback(osg::Texture2D* texture,osgText::Text* text,double delay=1.0):
532        _texture(texture),
533        _text(text),
534        _delay(delay),
535        _currPos(0),
536        _prevTime(0.0)
537    {
538
539       
540        _imageList.push_back(osgDB::readImageFile("Images/dog_left_eye.jpg"));
541        _textList.push_back("Subloaded Image 1 - dog_left_eye.jpg");
542       
543        _imageList.push_back(osgDB::readImageFile("Images/dog_right_eye.jpg"));
544        _textList.push_back("Subloaded Image 2 - dog_right_eye.jpg");
545       
546        setValues();
547    }
548
549    virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
550    {
551        if (nv->getFrameStamp())
552        {
553            double currTime = nv->getFrameStamp()->getSimulationTime();
554            if (currTime-_prevTime>_delay)
555            {
556                // update filter modes and text.
557                setValues();
558               
559                // advance the current positon, wrap round if required.
560                _currPos++;
561                if (_currPos>=_imageList.size()) _currPos=0;                   
562               
563                // record time
564                _prevTime = currTime;
565            }
566        }
567    }
568   
569    void setValues()
570    {
571        // Note, as long as the images are the same dimensions subloading will be used
572        // to update the textures.  If dimensions change then the texture objects have
573        // to be deleted and re-recreated.
574        //
575        // The load/subload happens during the draw traversal so doesn't happen on
576        // the setImage which just updates internal pointers and modifed flags.
577
578        _texture->setImage(_imageList[_currPos].get());
579       
580        //_texture->dirtyTextureObject();
581
582        _text->setText(_textList[_currPos]);
583    }
584
585protected:
586
587    typedef std::vector< osg::ref_ptr<osg::Image> > ImageList;
588    typedef std::vector<std::string>                TextList;
589
590    osg::ref_ptr<osg::Texture2D>    _texture;
591    osg::ref_ptr<osgText::Text>     _text;
592    double                          _delay;
593   
594    ImageList                       _imageList;
595    TextList                        _textList;
596   
597    unsigned int                    _currPos;
598    double                          _prevTime;
599   
600};
601
602osg::Node* createSubloadWall(osg::BoundingBox& bb)
603{
604    osg::Group* group = new osg::Group;
605   
606    // left hand side of bounding box.
607    osg::Vec3 top_left(bb.xMin(),bb.yMax(),bb.zMax());
608    osg::Vec3 bottom_left(bb.xMin(),bb.yMax(),bb.zMin());
609    osg::Vec3 bottom_right(bb.xMax(),bb.yMax(),bb.zMin());
610    osg::Vec3 top_right(bb.xMax(),bb.yMax(),bb.zMax());
611    osg::Vec3 center((bb.xMax()+bb.xMin())*0.5f,bb.yMax(),(bb.zMin()+bb.zMax())*0.5f);   
612    float height = bb.zMax()-bb.zMin();
613   
614    // create the geometry for the wall.
615    osg::Geometry* geom = new osg::Geometry;
616   
617    osg::Vec3Array* vertices = new osg::Vec3Array(4);
618    (*vertices)[0] = top_left;
619    (*vertices)[1] = bottom_left;
620    (*vertices)[2] = bottom_right;
621    (*vertices)[3] = top_right;
622    geom->setVertexArray(vertices);
623   
624    osg::Vec2Array* texcoords = new osg::Vec2Array(4);
625    (*texcoords)[0].set(0.0f,1.0f);
626    (*texcoords)[1].set(0.0f,0.0f);
627    (*texcoords)[2].set(1.0f,0.0f);
628    (*texcoords)[3].set(1.0f,1.0f);
629    geom->setTexCoordArray(0,texcoords);
630
631    osg::Vec3Array* normals = new osg::Vec3Array(1);
632    (*normals)[0].set(0.0f,-1.0f,0.0f);
633    geom->setNormalArray(normals);
634    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
635   
636    osg::Vec4Array* colors = new osg::Vec4Array(1);
637    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
638    geom->setColorArray(colors);
639    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
640
641    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
642   
643    osg::Geode* geom_geode = new osg::Geode;
644    geom_geode->addDrawable(geom);
645    group->addChild(geom_geode);
646   
647   
648    // set up the texture state.   
649    osg::Texture2D* texture = new osg::Texture2D;
650    texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
651    texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
652    texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
653   
654    osg::StateSet* stateset = geom->getOrCreateStateSet();
655    stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
656   
657    // create the text label.
658   
659    osgText::Text* text = new osgText::Text;
660    text->setDataVariance(osg::Object::DYNAMIC);
661    text->setFont("fonts/arial.ttf");
662    text->setPosition(center);
663    text->setCharacterSize(height*0.03f);
664    text->setAlignment(osgText::Text::CENTER_CENTER);
665    text->setAxisAlignment(osgText::Text::XZ_PLANE);
666   
667    osg::Geode* text_geode = new osg::Geode;
668    text_geode->addDrawable(text);
669   
670    osg::StateSet* text_stateset = text_geode->getOrCreateStateSet();
671    text_stateset->setAttributeAndModes(new osg::PolygonOffset(-1.0f,-1.0f),osg::StateAttribute::ON);
672   
673    group->addChild(text_geode);
674
675    // set the update callback to cycle through the various min and mag filter modes.
676    group->setUpdateCallback(new ImageUpdateCallback(texture,text));
677   
678    return group;
679   
680}
681
682
683osg::Node* createModel()
684{
685
686    // create the root node which will hold the model.
687    osg::Group* root = new osg::Group();
688   
689    // turn off lighting
690    root->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
691
692    osg::BoundingBox bb(0.0f,0.0f,0.0f,1.0f,1.0f,1.0f);
693
694    root->addChild(createFilterWall(bb,"Images/lz.rgb"));
695    root->addChild(createAnisotripicWall(bb,"Images/primitives.gif"));
696    root->addChild(createWrapWall(bb,"Images/tree0.rgba"));
697    root->addChild(createSubloadWall(bb));
698   
699    return root;
700}
701
702int main(int , char **)
703{
704    // construct the viewer.
705    osgViewer::Viewer viewer;
706
707    // add model to viewer.
708    viewer.setSceneData( createModel() );
709
710    return viewer.run();
711}
Note: See TracBrowser for help on using the browser.