root/OpenSceneGraph/trunk/examples/osgtext/osgtext.cpp @ 13347

Revision 12289, 24.6 kB (checked in by robert, 4 years ago)

Cleaned up example

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgtext.
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 <osgUtil/Optimizer>
20
21#include <osgDB/ReadFile>
22#include <osgDB/WriteFile>
23#include <osgDB/Registry>
24
25#include <osgGA/StateSetManipulator>
26#include <osgViewer/Viewer>
27#include <osgViewer/ViewerEventHandlers>
28
29#include <osg/Geode>
30#include <osg/Camera>
31#include <osg/ShapeDrawable>
32#include <osg/Sequence>
33#include <osg/PolygonMode>
34#include <osg/io_utils>
35
36#include <osgText/Font>
37#include <osgText/Text>
38
39
40osg::Group* createHUDText()
41{
42
43    osg::Group* rootNode = new osg::Group;
44
45    osgText::Font* font = osgText::readFontFile("fonts/arial.ttf");
46
47    osg::Geode* geode  = new osg::Geode;
48    rootNode->addChild(geode);
49
50    float windowHeight = 1024.0f;
51    float windowWidth = 1280.0f;
52    float margin = 50.0f;
53
54
55////////////////////////////////////////////////////////////////////////////////////////////////////////
56//   
57// Examples of how to set up different text layout
58//
59
60    osg::Vec4 layoutColor(1.0f,1.0f,0.0f,1.0f);
61    float layoutCharacterSize = 20.0f;   
62   
63    {
64        osgText::Text* text = new osgText::Text;
65        text->setFont(font);
66        text->setColor(layoutColor);
67        text->setCharacterSize(layoutCharacterSize);
68        text->setPosition(osg::Vec3(margin,windowHeight-margin,0.0f));
69
70        // the default layout is left to right, typically used in languages
71        // originating from europe such as English, French, German, Spanish etc..
72        text->setLayout(osgText::Text::LEFT_TO_RIGHT);
73
74        text->setText("text->setLayout(osgText::Text::LEFT_TO_RIGHT);");
75        geode->addDrawable(text);
76    }
77
78    {
79        osgText::Text* text = new osgText::Text;
80        text->setFont(font);
81        text->setColor(layoutColor);
82        text->setCharacterSize(layoutCharacterSize);
83        text->setPosition(osg::Vec3(windowWidth-margin,windowHeight-margin,0.0f));
84
85        // right to left layouts would be used for hebrew or arabic fonts.
86        text->setLayout(osgText::Text::RIGHT_TO_LEFT);
87        text->setAlignment(osgText::Text::RIGHT_BASE_LINE);
88
89        text->setText("text->setLayout(osgText::Text::RIGHT_TO_LEFT);");
90        geode->addDrawable(text);
91    }
92
93    {
94        osgText::Text* text = new osgText::Text;
95        text->setFont(font);
96        text->setColor(layoutColor);
97        text->setPosition(osg::Vec3(margin,windowHeight-margin,0.0f));
98        text->setCharacterSize(layoutCharacterSize);
99
100        // vertical font layout would be used for asian fonts.
101        text->setLayout(osgText::Text::VERTICAL);
102
103        text->setText("text->setLayout(osgText::Text::VERTICAL);");
104        geode->addDrawable(text);
105    }
106   
107   
108////////////////////////////////////////////////////////////////////////////////////////////////////////
109//   
110// Examples of how to set up different font resolution
111//
112
113    osg::Vec4 fontSizeColor(0.0f,1.0f,1.0f,1.0f);
114    float fontSizeCharacterSize = 30;
115   
116    osg::Vec3 cursor = osg::Vec3(margin*2,windowHeight-margin*2,0.0f);
117   
118    {
119        osgText::Text* text = new osgText::Text;
120        text->setFont(font);
121        text->setColor(fontSizeColor);
122        text->setCharacterSize(fontSizeCharacterSize);
123        text->setPosition(cursor);
124       
125        // use text that uses 10 by 10 texels as a target resolution for fonts.
126        text->setFontResolution(10,10); // blocky but small texture memory usage
127       
128        text->setText("text->setFontResolution(10,10); // blocky but small texture memory usage");
129        geode->addDrawable(text);
130    }
131   
132    cursor.y() -= fontSizeCharacterSize;
133    {
134        osgText::Text* text = new osgText::Text;
135        text->setFont(font);
136        text->setColor(fontSizeColor);
137        text->setCharacterSize(fontSizeCharacterSize);
138        text->setPosition(cursor);
139       
140        // use text that uses 20 by 20 texels as a target resolution for fonts.
141        text->setFontResolution(20,20); // smoother but higher texture memory usage (but still quite low).
142       
143        text->setText("text->setFontResolution(20,20); // smoother but higher texture memory usage (but still quite low).");
144        geode->addDrawable(text);
145    }
146   
147    cursor.y() -= fontSizeCharacterSize;
148    {
149        osgText::Text* text = new osgText::Text;
150        text->setFont(font);
151        text->setColor(fontSizeColor);
152        text->setCharacterSize(fontSizeCharacterSize);
153        text->setPosition(cursor);
154       
155        // use text that uses 40 by 40 texels as a target resolution for fonts.
156        text->setFontResolution(40,40); // even smoother but again higher texture memory usage.
157       
158        text->setText("text->setFontResolution(40,40); // even smoother but again higher texture memory usage.");
159        geode->addDrawable(text);
160    }
161
162
163////////////////////////////////////////////////////////////////////////////////////////////////////////
164//   
165// Examples of how to set up different sized text
166//
167
168    osg::Vec4 characterSizeColor(1.0f,0.0f,1.0f,1.0f);
169   
170    cursor.y() -= fontSizeCharacterSize*2.0f;
171   
172    {
173        osgText::Text* text = new osgText::Text;
174        text->setFont(font);
175        text->setColor(characterSizeColor);
176        text->setFontResolution(20,20);
177        text->setPosition(cursor);
178       
179        // use text that is 20 units high.
180        text->setCharacterSize(20); // small
181       
182        text->setText("text->setCharacterSize(20.0f); // small");
183        geode->addDrawable(text);
184    }
185   
186    cursor.y() -= 30.0f;
187    {
188        osgText::Text* text = new osgText::Text;
189        text->setFont(font);
190        text->setColor(characterSizeColor);
191        text->setFontResolution(30,30);
192        text->setPosition(cursor);
193       
194        // use text that is 30 units high.
195        text->setCharacterSize(30.0f); // medium
196       
197        text->setText("text->setCharacterSize(30.0f); // medium");
198        geode->addDrawable(text);
199    }
200   
201    cursor.y() -= 50.0f;
202    {
203        osgText::Text* text = new osgText::Text;
204        text->setFont(font);
205        text->setColor(characterSizeColor);
206        text->setFontResolution(40,40);
207        text->setPosition(cursor);
208       
209        // use text that is 60 units high.
210        text->setCharacterSize(60.0f); // large
211       
212        text->setText("text->setCharacterSize(60.0f); // large");
213        geode->addDrawable(text);
214    }
215
216
217////////////////////////////////////////////////////////////////////////////////////////////////////////
218//   
219// Examples of how to set up different alignments
220//
221
222    osg::Vec4 alignmentSizeColor(0.0f,1.0f,0.0f,1.0f);
223    float alignmentCharacterSize = 25.0f;
224    cursor.x() = 640;
225    cursor.y() = margin*4.0f;
226   
227    typedef std::pair<osgText::Text::AlignmentType,std::string> AlignmentPair;
228    typedef std::vector<AlignmentPair> AlignmentList;
229    AlignmentList alignmentList;
230    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_TOP,"text->setAlignment(\nosgText::Text::LEFT_TOP);"));
231    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_CENTER,"text->setAlignment(\nosgText::Text::LEFT_CENTER);"));
232    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_BOTTOM,"text->setAlignment(\nosgText::Text::LEFT_BOTTOM);"));
233    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_TOP,"text->setAlignment(\nosgText::Text::CENTER_TOP);"));
234    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_CENTER,"text->setAlignment(\nosgText::Text::CENTER_CENTER);"));
235    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_BOTTOM,"text->setAlignment(\nosgText::Text::CENTER_BOTTOM);"));
236    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_TOP,"text->setAlignment(\nosgText::Text::RIGHT_TOP);"));
237    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_CENTER,"text->setAlignment(\nosgText::Text::RIGHT_CENTER);"));
238    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_BOTTOM,"text->setAlignment(\nosgText::Text::RIGHT_BOTTOM);"));
239    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_BASE_LINE,"text->setAlignment(\nosgText::Text::LEFT_BASE_LINE);"));
240    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_BASE_LINE,"text->setAlignment(\nosgText::Text::CENTER_BASE_LINE);"));
241    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_BASE_LINE,"text->setAlignment(\nosgText::Text::RIGHT_BASE_LINE);"));
242    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_BOTTOM_BASE_LINE,"text->setAlignment(\nosgText::Text::LEFT_BOTTOM_BASE_LINE);"));
243    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_BOTTOM_BASE_LINE,"text->setAlignment(\nosgText::Text::CENTER_BOTTOM_BASE_LINE);"));
244    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_BOTTOM_BASE_LINE,"text->setAlignment(\nosgText::Text::RIGHT_BOTTOM_BASE_LINE);"));
245
246
247    osg::Sequence* sequence = new osg::Sequence;
248    {
249        for(AlignmentList::iterator itr=alignmentList.begin();
250            itr!=alignmentList.end();
251            ++itr)
252        {
253            osg::Geode* alignmentGeode = new osg::Geode;
254            sequence->addChild(alignmentGeode);
255            sequence->setTime(sequence->getNumChildren(), 1.0f);
256
257            osgText::Text* text = new osgText::Text;
258            text->setFont(font);
259            text->setColor(alignmentSizeColor);
260            text->setCharacterSize(alignmentCharacterSize);
261            text->setPosition(cursor);
262            text->setDrawMode(osgText::Text::TEXT|osgText::Text::ALIGNMENT|osgText::Text::BOUNDINGBOX);
263           
264            text->setAlignment(itr->first);
265            text->setText(itr->second);
266           
267            alignmentGeode->addDrawable(text);
268
269
270        }
271       
272    }
273
274    sequence->setMode(osg::Sequence::START);
275    sequence->setInterval(osg::Sequence::LOOP, 0, -1);
276    sequence->setDuration(1.0f, -1);
277   
278    rootNode->addChild(sequence);
279
280
281////////////////////////////////////////////////////////////////////////////////////////////////////////
282//   
283// Examples of how to set up different fonts...
284//
285
286    cursor.x() = margin*2.0f;
287    cursor.y() = margin*2.0f;
288   
289    osg::Vec4 fontColor(1.0f,0.5f,0.0f,1.0f);
290    float fontCharacterSize = 20.0f;
291    float spacing = 40.0f;
292   
293    {
294        osgText::Text* text = new osgText::Text;
295        text->setColor(fontColor);
296        text->setPosition(cursor);
297        text->setCharacterSize(fontCharacterSize);
298       
299        text->setFont(0);
300        text->setText("text->setFont(0); // inbuilt font.");
301        geode->addDrawable(text);
302
303        cursor.x() = text->getBound().xMax() + spacing ;
304    }
305   
306    {
307        osgText::Font* arial = osgText::readFontFile("fonts/arial.ttf");
308
309        osgText::Text* text = new osgText::Text;
310        text->setColor(fontColor);
311        text->setPosition(cursor);
312        text->setCharacterSize(fontCharacterSize);
313       
314        text->setFont(arial);
315        text->setText(arial!=0?
316                      "text->setFont(\"fonts/arial.ttf\");":
317                      "unable to load \"fonts/arial.ttf\"");
318        geode->addDrawable(text);
319
320        cursor.x() = text->getBound().xMax() + spacing ;
321    }
322   
323    {
324        osgText::Font* times = osgText::readFontFile("fonts/times.ttf");
325
326        osgText::Text* text = new osgText::Text;
327        text->setColor(fontColor);
328        text->setPosition(cursor);
329        text->setCharacterSize(fontCharacterSize);
330       
331        geode->addDrawable(text);
332        text->setFont(times);
333        text->setText(times!=0?
334                      "text->setFont(\"fonts/times.ttf\");":
335                      "unable to load \"fonts/times.ttf\"");
336
337        cursor.x() = text->getBound().xMax() + spacing ;
338    }
339   
340    cursor.x() = margin*2.0f;
341    cursor.y() = margin;
342
343    {
344        osgText::Font* dirtydoz = osgText::readFontFile("fonts/dirtydoz.ttf");
345
346        osgText::Text* text = new osgText::Text;
347        text->setColor(fontColor);
348        text->setPosition(cursor);
349        text->setCharacterSize(fontCharacterSize);
350       
351        text->setFont(dirtydoz);
352        text->setText(dirtydoz!=0?
353                      "text->setFont(\"fonts/dirtydoz.ttf\");":
354                      "unable to load \"fonts/dirtydoz.ttf\"");
355        geode->addDrawable(text);
356
357        cursor.x() = text->getBound().xMax() + spacing ;
358    }
359   
360    {
361        osgText::Font* fudd = osgText::readFontFile("fonts/fudd.ttf");
362   
363        osgText::Text* text = new osgText::Text;
364        text->setColor(fontColor);
365        text->setPosition(cursor);
366        text->setCharacterSize(fontCharacterSize);
367       
368        text->setFont(fudd);
369        text->setText(fudd!=0?
370                      "text->setFont(\"fonts/fudd.ttf\");":
371                      "unable to load \"fonts/fudd.ttf\"");
372        geode->addDrawable(text);
373
374        cursor.x() = text->getBound().xMax() + spacing ;
375    }
376           
377    return rootNode;   
378}
379
380
381
382
383// create text which sits in 3D space such as would be inserted into a normal model
384osg::Group* create3DText(const osg::Vec3& center,float radius)
385{
386
387    osg::Geode* geode  = new osg::Geode;
388
389   
390////////////////////////////////////////////////////////////////////////////////////////////////////////
391//   
392// Examples of how to set up axis/orientation alignments
393//
394
395    float characterSize=radius*0.2f;
396
397
398    osg::Vec3 pos(center.x()-radius*.5f,center.y()-radius*.5f,center.z()-radius*.5f);
399
400    osgText::Text* text1 = new osgText::Text;
401    text1->setFont("fonts/times.ttf");
402    text1->setCharacterSize(characterSize);
403    text1->setPosition(pos);
404    text1->setAxisAlignment(osgText::Text::XY_PLANE);
405    text1->setText("XY_PLANE");
406    geode->addDrawable(text1);
407
408    osgText::Text* text2 = new osgText::Text;
409    text2->setFont("fonts/times.ttf");
410    text2->setCharacterSize(characterSize);
411    text2->setPosition(pos);
412    text2->setAxisAlignment(osgText::Text::YZ_PLANE);
413    text2->setText("YZ_PLANE");
414    geode->addDrawable(text2);
415
416    osgText::Text* text3 = new osgText::Text;
417    text3->setFont("fonts/times.ttf");
418    text3->setCharacterSize(characterSize);
419    text3->setPosition(pos);
420    text3->setAxisAlignment(osgText::Text::XZ_PLANE);
421    text3->setText("XZ_PLANE");
422    geode->addDrawable(text3);
423
424    osg::Vec4 characterSizeModeColor(1.0f,0.0f,0.5f,1.0f);
425
426    osgText::Text* text4 = new osgText::Text;
427    text4->setFont("fonts/times.ttf");
428    text4->setCharacterSize(characterSize);
429    text4->setPosition(center);
430    text4->setAxisAlignment(osgText::Text::SCREEN);
431
432    // reproduce outline bounding box compute problem with backdrop on.
433    text4->setBackdropType(osgText::Text::OUTLINE);
434    text4->setDrawMode(osgText::Text::TEXT | osgText::Text::BOUNDINGBOX);
435
436    text4->setText("SCREEN");
437    geode->addDrawable(text4);
438
439    osgText::Text* text5 = new osgText::Text;
440    text5->setColor(characterSizeModeColor);
441    text5->setFont("fonts/times.ttf");
442    //text5->setCharacterSize(characterSize);
443    text5->setCharacterSize(32.0f); // medium
444    text5->setPosition(center - osg::Vec3(0.0, 0.0, 0.2));
445    text5->setAxisAlignment(osgText::Text::SCREEN);
446    text5->setCharacterSizeMode(osgText::Text::SCREEN_COORDS);
447    text5->setDrawMode(osgText::Text::TEXT | osgText::Text::BOUNDINGBOX);
448    text5->setText("CharacterSizeMode SCREEN_COORDS(size 32.0)");
449    geode->addDrawable(text5);
450
451    osgText::Text* text6 = new osgText::Text;
452    text6->setColor(characterSizeModeColor);
453    text6->setFont("fonts/times.ttf");
454    text6->setCharacterSize(characterSize);
455    text6->setPosition(center - osg::Vec3(0.0, 0.0, 0.4));
456    text6->setAxisAlignment(osgText::Text::SCREEN);
457    text6->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);
458    text6->setText("CharacterSizeMode OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT");
459    geode->addDrawable(text6);
460
461    osgText::Text* text7 = new osgText::Text;
462    text7->setColor(characterSizeModeColor);
463    text7->setFont("fonts/times.ttf");
464    text7->setCharacterSize(characterSize);
465    text7->setPosition(center - osg::Vec3(0.0, 0.0, 0.6));
466    text7->setAxisAlignment(osgText::Text::SCREEN);
467    text7->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
468    text7->setText("CharacterSizeMode OBJECT_COORDS (default)");
469    geode->addDrawable(text7);
470
471
472
473    osg::ShapeDrawable* shape = new osg::ShapeDrawable(new osg::Sphere(center,characterSize*0.2f));
474    shape->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::ON);
475    geode->addDrawable(shape);
476
477    osg::Group* rootNode = new osg::Group;
478    rootNode->addChild(geode);
479
480    return rootNode;   
481}
482
483class UpdateTextOperation : public osg::Operation
484{
485public:
486
487    UpdateTextOperation(const osg::Vec3& center, float diameter, osg::Group* group):       
488        Operation("UpdateTextOperation", true),
489        _center(center),
490        _diameter(diameter),
491        _maxNumChildren(200),
492        _maxNumTextPerGeode(10),
493        _group(group)
494    {
495    }
496
497    virtual void operator () (osg::Object* callingObject)
498    {
499        // decided which method to call according to whole has called me.
500        osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(callingObject);
501
502        if (viewer) update();
503        else load();
504    }
505   
506    void update()
507    {
508        // osg::notify(osg::NOTICE)<<"*** Doing update"<<std::endl;
509       
510        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
511       
512        if (_mergeSubgraph.valid())
513        {
514            _group->addChild(_mergeSubgraph.get());
515
516            _mergeSubgraph = 0;
517
518            if (_group->getNumChildren()>_maxNumChildren)
519            {
520                osg::Geode* geode = dynamic_cast<osg::Geode*>(_group->getChild(0));
521                if (geode)
522                {
523                    _availableSubgraph.push_back(geode);
524                    geode->removeDrawables(0,geode->getNumDrawables());
525                }
526                _group->removeChild(0,1);
527            }
528           
529            _waitOnMergeBlock.release();
530        }       
531    }
532   
533    void load()
534    {
535   
536        // osg::notify(osg::NOTICE)<<"Doing load"<<std::endl;
537
538        osg::ref_ptr<osg::Geode> geode;
539        {
540            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
541            if (!_availableSubgraph.empty())
542            {
543                geode = _availableSubgraph.front();
544                _availableSubgraph.pop_front();
545            }
546        }
547       
548        if (!geode) geode = new osg::Geode;
549
550        for(unsigned int i=0; i<_maxNumTextPerGeode; ++i)
551        {
552            float x = float(rand()) / float(RAND_MAX) - 0.5f;
553            float y = float(rand()) / float(RAND_MAX) - 0.5f;
554            float z = float(i)      / float(_maxNumTextPerGeode) - 0.5f;
555            osg::Vec3 position(x, y, z);
556
557            std::string str;
558            unsigned int _numCharacters = 5;
559            for(unsigned int ni=0; ni<_numCharacters;++ni)
560            {
561                str.push_back(char(32.0 + (float(rand())/float(RAND_MAX))*128.0f));
562            }
563                       
564            osgText::Text* text = new osgText::Text;
565            text->setDataVariance(osg::Object::DYNAMIC);
566            text->setPosition(_center + position * _diameter);
567            text->setFont("times.ttf");
568            text->setText(str);
569            text->setCharacterSize(0.025f * _diameter);
570            text->setAxisAlignment(osgText::Text::SCREEN);
571           
572            geode->addDrawable(text);
573        }
574
575
576        {       
577            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
578            _mergeSubgraph = geode;
579        }
580       
581        // osg::notify(osg::NOTICE)<<"Waiting on merge"<<std::endl;
582
583        _waitOnMergeBlock.block();
584
585    }
586   
587    virtual void release()
588    {
589        _waitOnMergeBlock.release();
590    }
591
592    typedef std::list< osg::ref_ptr<osg::Geode> > AvailableList;
593
594    osg::Vec3                   _center;
595    float                       _diameter;
596    unsigned int                _maxNumChildren;
597    unsigned int                _maxNumTextPerGeode;
598   
599    OpenThreads::Mutex          _mutex;
600    osg::ref_ptr<osg::Group>    _group;
601    osg::ref_ptr<osg::Geode>    _mergeSubgraph;
602    AvailableList               _availableSubgraph;
603    OpenThreads::Block          _waitOnMergeBlock;
604   
605    unsigned int                _counter;
606
607};
608
609
610int main(int argc, char** argv)
611{
612    osg::ArgumentParser arguments(&argc, argv);
613
614    // construct the viewer.
615    osgViewer::Viewer viewer(arguments);
616   
617    typedef std::list< osg::ref_ptr<osg::OperationThread> > Threads;
618
619    Threads operationThreads;
620    osg::ref_ptr<UpdateTextOperation> updateOperation;
621
622    unsigned int numThreads = 0;
623    if (arguments.read("--mt", numThreads) || arguments.read("--mt"))
624    {
625        // construct a multi-threaded text updating test.
626        if (numThreads==0) numThreads = 1;
627       
628        // create a group to add everything into.
629        osg::Group* mainGroup = new osg::Group;
630       
631        osg::Vec3 center(0.5f,0.5f,0.5f);
632        float diameter = 1.0f;
633       
634        osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
635        if (loadedModel.valid())
636        {
637            mainGroup->addChild(loadedModel.get());
638           
639            center = loadedModel->getBound().center();
640            diameter = loadedModel->getBound().radius() * 2.0f;
641        }
642       
643        for(unsigned int i=0; i<numThreads; ++i)
644        {
645            osg::Group* textGroup = new osg::Group;
646            mainGroup->addChild(textGroup);
647
648            // create the background thread
649            osg::OperationThread* operationThread = new osg::OperationThread;
650           
651            operationThreads.push_back(operationThread);
652
653            // create the operation that will run in the background and
654            // sync once per frame with the main viewer loop.
655            updateOperation = new UpdateTextOperation(center, diameter, textGroup);
656
657            // add the operation to the operation thread and start it.
658            operationThread->add(updateOperation.get());
659            operationThread->startThread();
660
661            // add the operation to the viewer to sync once per frame.
662            viewer.addUpdateOperation(updateOperation.get());
663
664
665            // add a unit cube for the text to appear within.
666            osg::Geode* geode = new osg::Geode;
667            geode->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE));
668            geode->addDrawable(new osg::ShapeDrawable(new osg::Box(center,diameter)));
669
670            mainGroup->addChild(geode);
671        }
672               
673        viewer.setSceneData(mainGroup);       
674    }
675    else
676    {
677        // prepare scene.
678        osg::Vec3 center(0.0f,0.0f,0.0f);
679        float radius = 1.0f;
680       
681        // make sure the root node is group so we can add extra nodes to it.
682        osg::Group* group = new osg::Group;
683
684        if (true)
685        {
686            // create the hud.
687            osg::Camera* camera = new osg::Camera;
688            camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
689            camera->setProjectionMatrixAsOrtho2D(0,1280,0,1024);
690            camera->setViewMatrix(osg::Matrix::identity());
691            camera->setClearMask(GL_DEPTH_BUFFER_BIT);
692            camera->addChild(createHUDText());
693            camera->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
694
695            group->addChild(camera);
696        }
697
698        if (true)
699        {
700            group->addChild(create3DText(center,radius));
701        }
702
703        // set the scene to render
704        viewer.setSceneData(group);
705    }
706
707    std::string filename;
708    if (arguments.read("-o",filename))
709    {
710        osgDB::writeNodeFile(*viewer.getSceneData(),filename);
711        return 0;
712    }
713
714    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
715    viewer.addEventHandler(new osgViewer::StatsHandler());
716
717    viewer.run();
718   
719    if (!operationThreads.empty())
720    {
721        for(Threads::iterator itr = operationThreads.begin();
722            itr != operationThreads.end();
723            ++itr)
724        {
725            (*itr)->cancel();
726        }
727    }
728
729    return 0;
730}
Note: See TracBrowser for help on using the browser.