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

Revision 7867, 24.3 kB (checked in by robert, 7 years ago)

From Philip Lowman, workaround for gcc 3.2.3 bug

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