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

Revision 1832, 17.6 kB (checked in by robert, 12 years ago)

Changed the Viewer::realize() calls across to not using the threading paramter
leaving it up to the Viewer to specify the mode (which by default is MultiThreaded?).
Added a check for the presence of osgParticle systems so that threading is
disabled in this case.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <osgUtil/Optimizer>
15
16#include <osgDB/ReadFile>
17#include <osgDB/WriteFile>
18#include <osgDB/Registry>
19
20#include <osgProducer/Viewer>
21
22#include <osg/Geode>
23#include <osg/Projection>
24#include <osg/MatrixTransform>
25#include <osg/ShapeDrawable>
26#include <osg/Sequence>
27
28#include <osgText/Font>
29#include <osgText/Text>
30
31
32osg::Group* createHUDText()
33{
34
35    osg::Group* rootNode = new osg::Group;
36
37    osgText::Font* font = osgText::readFontFile("fonts/arial.ttf");
38
39    osg::Geode* geode  = new osg::Geode;
40    rootNode->addChild(geode);
41
42    float windowHeight = 1024.0f;
43    float windowWidth = 1280.0f;
44    float margin = 50.0f;
45
46
47////////////////////////////////////////////////////////////////////////////////////////////////////////
48//   
49// Examples of how to set up different text layout
50//
51
52    osg::Vec4 layoutColor(1.0f,1.0f,0.0f,1.0f);
53    float layoutCharacterSize = 20.0f;   
54   
55    {
56        osgText::Text* text = new osgText::Text;
57        text->setFont(font);
58        text->setColor(layoutColor);
59        text->setCharacterSize(layoutCharacterSize);
60        text->setPosition(osg::Vec3(margin,windowHeight-margin,0.0f));
61
62        // the default layout is left to right, typically used in languages
63        // originating from europe such as English, French, German, Spanish etc..
64        text->setLayout(osgText::Text::LEFT_TO_RIGHT);
65
66        text->setText("text->setLayout(osgText::Text::LEFT_TO_RIGHT);");
67        geode->addDrawable(text);
68    }
69
70    {
71        osgText::Text* text = new osgText::Text;
72        text->setFont(font);
73        text->setColor(layoutColor);
74        text->setCharacterSize(layoutCharacterSize);
75        text->setPosition(osg::Vec3(windowWidth-margin,windowHeight-margin,0.0f));
76
77        // right to left layouts would be used for hebrew or arabic fonts.
78        text->setLayout(osgText::Text::RIGHT_TO_LEFT);
79
80        text->setText("text->setLayout(osgText::Text::RIGHT_TO_LEFT);");
81        geode->addDrawable(text);
82    }
83
84    {
85        osgText::Text* text = new osgText::Text;
86        text->setFont(font);
87        text->setColor(layoutColor);
88        text->setPosition(osg::Vec3(margin,windowHeight-margin,0.0f));
89        text->setCharacterSize(layoutCharacterSize);
90
91        // vertical font layout would be used for asian fonts.
92        text->setLayout(osgText::Text::VERTICAL);
93
94        text->setText("text->setLayout(osgText::Text::VERTICAL);");
95        geode->addDrawable(text);
96    }
97   
98   
99////////////////////////////////////////////////////////////////////////////////////////////////////////
100//   
101// Examples of how to set up different font resolution
102//
103
104    osg::Vec4 fontSizeColor(0.0f,1.0f,1.0f,1.0f);
105    float fontSizeCharacterSize = 30;
106   
107    osg::Vec3 cursor = osg::Vec3(margin*2,windowHeight-margin*2,0.0f);
108   
109    {
110        osgText::Text* text = new osgText::Text;
111        text->setFont(font);
112        text->setColor(fontSizeColor);
113        text->setCharacterSize(fontSizeCharacterSize);
114        text->setPosition(cursor);
115       
116        // use text that uses 10 by 10 texels as a target resolution for fonts.
117        text->setFontSize(10,10); // blocky but small texture memory usage
118       
119        text->setText("text->setFontSize(10,10); // blocky but small texture memory usage");
120        geode->addDrawable(text);
121    }
122   
123    cursor.y() -= fontSizeCharacterSize;
124    {
125        osgText::Text* text = new osgText::Text;
126        text->setFont(font);
127        text->setColor(fontSizeColor);
128        text->setCharacterSize(fontSizeCharacterSize);
129        text->setPosition(cursor);
130       
131        // use text that uses 10 by 10 texels as a target resolution for fonts.
132        text->setFontSize(20,20); // smoother but higher texture memory usage (but still quite low).
133       
134        text->setText("text->setFontSize(20,20); // smoother but higher texture memory usage (but still quite low).");
135        geode->addDrawable(text);
136    }
137   
138    cursor.y() -= fontSizeCharacterSize;
139    {
140        osgText::Text* text = new osgText::Text;
141        text->setFont(font);
142        text->setColor(fontSizeColor);
143        text->setCharacterSize(fontSizeCharacterSize);
144        text->setPosition(cursor);
145       
146        // use text that uses 10 by 10 texels as a target resolution for fonts.
147        text->setFontSize(40,40); // even smoother but again higher texture memory usage.
148       
149        text->setText("text->setFontSize(40,40); // even smoother but again higher texture memory usage.");
150        geode->addDrawable(text);
151    }
152
153
154////////////////////////////////////////////////////////////////////////////////////////////////////////
155//   
156// Examples of how to set up different sized text
157//
158
159    osg::Vec4 characterSizeColor(1.0f,0.0f,1.0f,1.0f);
160   
161    cursor.y() -= fontSizeCharacterSize*2.0f;
162   
163    {
164        osgText::Text* text = new osgText::Text;
165        text->setFont(font);
166        text->setColor(characterSizeColor);
167        text->setFontSize(20,20);
168        text->setPosition(cursor);
169       
170        // use text that 20 units high.
171        text->setCharacterSize(20); // small
172       
173        text->setText("text->setCharacterSize(15.0f); // small");
174        geode->addDrawable(text);
175    }
176   
177    cursor.y() -= 30.0f;
178    {
179        osgText::Text* text = new osgText::Text;
180        text->setFont(font);
181        text->setColor(characterSizeColor);
182        text->setFontSize(30,30);
183        text->setPosition(cursor);
184       
185        // use text that 20 units high.
186        text->setCharacterSize(30.0f); // medium
187       
188        text->setText("text->setCharacterSize(30.0f); // medium");
189        geode->addDrawable(text);
190    }
191   
192    cursor.y() -= 50.0f;
193    {
194        osgText::Text* text = new osgText::Text;
195        text->setFont(font);
196        text->setColor(characterSizeColor);
197        text->setFontSize(40,40);
198        text->setPosition(cursor);
199       
200        // use text that uses 10 by 10 texels as a target resolution for fonts.
201        text->setCharacterSize(60.0f); // large
202       
203        text->setText("text->setCharacterSize(60.0f); // large");
204        geode->addDrawable(text);
205    }
206
207
208////////////////////////////////////////////////////////////////////////////////////////////////////////
209//   
210// Examples of how to set up different alignments
211//
212
213    osg::Vec4 alignmentSizeColor(0.0f,1.0f,0.0f,1.0f);
214    float alignmentCharacterSize = 25.0f;
215    cursor.x() = 640;
216    cursor.y() = margin*4.0f;
217   
218    typedef std::pair<osgText::Text::AlignmentType,std::string> AlignmentPair;
219    typedef std::vector<AlignmentPair> AlignmentList;
220    AlignmentList alignmentList;
221    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_TOP,"text->setAlignment(osgText::Text::LEFT_TOP);"));
222    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_CENTER,"text->setAlignment(osgText::Text::LEFT_CENTER);"));
223    alignmentList.push_back(AlignmentPair(osgText::Text::LEFT_BOTTOM,"text->setAlignment(osgText::Text::LEFT_BOTTOM);"));
224    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_TOP,"text->setAlignment(osgText::Text::CENTER_TOP);"));
225    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_CENTER,"text->setAlignment(osgText::Text::CENTER_CENTER);"));
226    alignmentList.push_back(AlignmentPair(osgText::Text::CENTER_BOTTOM,"text->setAlignment(osgText::Text::CENTER_BOTTOM);"));
227    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_TOP,"text->setAlignment(osgText::Text::RIGHT_TOP);"));
228    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_CENTER,"text->setAlignment(osgText::Text::RIGHT_CENTER);"));
229    alignmentList.push_back(AlignmentPair(osgText::Text::RIGHT_BOTTOM,"text->setAlignment(osgText::Text::RIGHT_BOTTOM);"));
230    alignmentList.push_back(AlignmentPair(osgText::Text::BASE_LINE,"text->setAlignment(osgText::Text::BASE_LINE);//default"));
231
232    osg::Sequence* sequence = new osg::Sequence;
233    {
234        for(AlignmentList::iterator itr=alignmentList.begin();
235            itr!=alignmentList.end();
236            ++itr)
237        {
238            osg::Geode* alignmentGeode = new osg::Geode;
239            sequence->addChild(alignmentGeode);
240            sequence->setTime(sequence->getNumChildren(), 1.0f);
241
242            osgText::Text* text = new osgText::Text;
243            text->setFont(font);
244            text->setColor(alignmentSizeColor);
245            text->setCharacterSize(alignmentCharacterSize);
246            text->setPosition(cursor);
247            text->setDrawMode(osgText::Text::TEXT|osgText::Text::ALIGNMENT|osgText::Text::BOUNDINGBOX);
248           
249            text->setAlignment(itr->first);
250            text->setText(itr->second);
251           
252            alignmentGeode->addDrawable(text);
253
254
255        }
256       
257    }
258
259    sequence->setMode(osg::Sequence::START);
260    sequence->setInterval(osg::Sequence::LOOP, 0, -1);
261    sequence->setDuration(1.0f, -1);
262   
263    rootNode->addChild(sequence);
264
265
266////////////////////////////////////////////////////////////////////////////////////////////////////////
267//   
268// Examples of how to set up different fonts...
269//
270
271    cursor.x() = margin*2.0f;
272    cursor.y() = margin*2.0f;
273   
274    osg::Vec4 fontColor(1.0f,0.5f,0.0f,1.0f);
275    float fontCharacterSize = 20.0f;
276    float spacing = 40.0f;
277   
278    {
279        osgText::Text* text = new osgText::Text;
280        text->setColor(fontColor);
281        text->setPosition(cursor);
282        text->setCharacterSize(fontCharacterSize);
283       
284        text->setFont(0);
285        text->setText("text->setFont(0); // inbuilt font.");
286        geode->addDrawable(text);
287
288        cursor.x() = text->getBound().xMax() + spacing ;
289    }
290   
291    {
292        osgText::Font* arial = osgText::readFontFile("fonts/arial.ttf");
293
294        osgText::Text* text = new osgText::Text;
295        text->setColor(fontColor);
296        text->setPosition(cursor);
297        text->setCharacterSize(fontCharacterSize);
298       
299        text->setFont(arial);
300        text->setText(arial!=0?
301                      "text->setFont(\"fonts/arial.ttf\");":
302                      "unable to load \"fonts/arial.ttf\"");
303        geode->addDrawable(text);
304
305        cursor.x() = text->getBound().xMax() + spacing ;
306    }
307   
308    {
309        osgText::Font* times = osgText::readFontFile("fonts/times.ttf");
310
311        osgText::Text* text = new osgText::Text;
312        text->setColor(fontColor);
313        text->setPosition(cursor);
314        text->setCharacterSize(fontCharacterSize);
315       
316        geode->addDrawable(text);
317        text->setFont(times);
318        text->setText(times!=0?
319                      "text->setFont(\"fonts/times.ttf\");":
320                      "unable to load \"fonts/times.ttf\"");
321
322        cursor.x() = text->getBound().xMax() + spacing ;
323    }
324   
325    cursor.x() = margin*2.0f;
326    cursor.y() = margin;
327
328    {
329        osgText::Font* dirtydoz = osgText::readFontFile("fonts/dirtydoz.ttf");
330
331        osgText::Text* text = new osgText::Text;
332        text->setColor(fontColor);
333        text->setPosition(cursor);
334        text->setCharacterSize(fontCharacterSize);
335       
336        text->setFont(dirtydoz);
337        text->setText(dirtydoz!=0?
338                      "text->setFont(\"fonts/dirtydoz.ttf\");":
339                      "unable to load \"fonts/dirtydoz.ttf\"");
340        geode->addDrawable(text);
341
342        cursor.x() = text->getBound().xMax() + spacing ;
343    }
344   
345    {
346        osgText::Font* fudd = osgText::readFontFile("fonts/fudd.ttf");
347   
348        osgText::Text* text = new osgText::Text;
349        text->setColor(fontColor);
350        text->setPosition(cursor);
351        text->setCharacterSize(fontCharacterSize);
352       
353        text->setFont(fudd);
354        text->setText(fudd!=0?
355                      "text->setFont(\"fonts/fudd.ttf\");":
356                      "unable to load \"fonts/fudd.ttf\"");
357        geode->addDrawable(text);
358
359        cursor.x() = text->getBound().xMax() + spacing ;
360    }
361           
362    return rootNode;   
363}
364
365
366
367
368// create text which sits in 3D space such as would be inserted into a normal model
369osg::Group* create3DText(const osg::Vec3& center,float radius)
370{
371
372    osg::Geode* geode  = new osg::Geode;
373
374////////////////////////////////////////////////////////////////////////////////////////////////////////
375//   
376// Examples of how to set up axis/orientation alignments
377//
378
379    float characterSize=radius*0.2f;
380   
381    osg::Vec3 pos(center.x()-radius*.5f,center.y()-radius*.5f,center.z()-radius*.5f);
382
383    osgText::Text* text1 = new osgText::Text;
384    text1->setFont("fonts/times.ttf");
385    text1->setCharacterSize(characterSize);
386    text1->setPosition(pos);
387    text1->setAxisAlignment(osgText::Text::XY_PLANE);
388    text1->setText("XY_PLANE");
389    geode->addDrawable(text1);
390
391    osgText::Text* text2 = new osgText::Text;
392    text2->setFont("fonts/times.ttf");
393    text2->setCharacterSize(characterSize);
394    text2->setPosition(pos);
395    text2->setAxisAlignment(osgText::Text::YZ_PLANE);
396    text2->setText("YZ_PLANE");
397    geode->addDrawable(text2);
398
399    osgText::Text* text3 = new osgText::Text;
400    text3->setFont("fonts/times.ttf");
401    text3->setCharacterSize(characterSize);
402    text3->setPosition(pos);
403    text3->setAxisAlignment(osgText::Text::XZ_PLANE);
404    text3->setText("XZ_PLANE");
405    geode->addDrawable(text3);
406
407
408    osgText::Text* text4 = new osgText::Text;
409    text4->setFont("fonts/times.ttf");
410    text4->setCharacterSize(characterSize);
411    text4->setPosition(center);
412    text4->setAxisAlignment(osgText::Text::SCREEN);
413    text4->setText("SCREEN");
414    geode->addDrawable(text4);
415
416    osg::ShapeDrawable* shape = new osg::ShapeDrawable(new osg::Sphere(center,characterSize*0.2f));
417    shape->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::ON);
418    geode->addDrawable(shape);
419
420
421    osg::Group* rootNode = new osg::Group;
422    rootNode->addChild(geode);
423
424    return rootNode;   
425}
426
427int main( int argc, char **argv )
428{
429    // use an ArgumentParser object to manage the program arguments.
430    osg::ArgumentParser arguments(&argc,argv);
431   
432    // set up the usage document, in case we need to print out how to use this program.
433    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] [filename] ...");
434    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
435   
436
437    // construct the viewer.
438    osgProducer::Viewer viewer(arguments);
439
440    // set up the value with sensible default event handlers.
441    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
442
443    // get details on keyboard and mouse bindings used by the viewer.
444    viewer.getUsage(*arguments.getApplicationUsage());
445
446    // if user request help write it out to cout.
447    if (arguments.read("-h") || arguments.read("--help"))
448    {
449        arguments.getApplicationUsage()->write(std::cout);
450        return 1;
451    }
452
453    // any option left unread are converted into errors to write out later.
454    arguments.reportRemainingOptionsAsUnrecognized();
455
456    // report any errors if they have occured when parsing the program aguments.
457    if (arguments.errors())
458    {
459        arguments.writeErrorMessages(std::cout);
460        return 1;
461    }
462   
463
464    // read the scene from the list of file specified commandline args.
465    osg::ref_ptr<osg::Node> rootNode = osgDB::readNodeFiles(arguments);
466
467    // prepare scene.
468    {
469
470        osg::Vec3 center(0.0f,0.0f,0.0f);
471        float radius = 1.0f;
472       
473        if (rootNode.valid())
474        {
475            // optimize the scene graph, remove rendundent nodes and state etc.
476            osgUtil::Optimizer optimizer;
477            optimizer.optimize(rootNode.get());
478           
479            const osg::BoundingSphere& bs = rootNode->getBound();
480            center = bs.center();
481            radius = bs.radius();
482        }
483
484        // make sure the root node is group so we can add extra nodes to it.
485        osg::Group* group = dynamic_cast<osg::Group*>(rootNode.get());
486        if (!group)
487        {
488            group = new osg::Group;
489           
490            if (rootNode.valid()) group->addChild(rootNode.get());
491           
492            rootNode = group;
493        }
494
495        {
496            // create the hud.
497            osg::Projection* projection = new osg::Projection;
498            projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
499
500            osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
501            modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE);
502            modelview_abs->setMatrix(osg::Matrix::identity());
503
504            modelview_abs->addChild(createHUDText());
505
506            projection->addChild(modelview_abs);
507
508            group->addChild(projection);
509        }
510
511        group->addChild(create3DText(center,radius));
512
513    }
514
515    // set the scene to render
516    viewer.setSceneData(rootNode.get());
517
518    // create the windows and run the threads.
519    viewer.realize();
520
521    while( !viewer.done() )
522    {
523        // wait for all cull and draw threads to complete.
524        viewer.sync();
525
526        // update the scene by traversing it with the the update visitor which will
527        // call all node update callbacks and animations.
528        viewer.update();
529         
530        // fire off the cull and draw traversals of the scene.
531        viewer.frame();
532       
533    }
534   
535    // wait for all cull and draw threads to complete before exit.
536    viewer.sync();
537
538    return 0;
539}
Note: See TracBrowser for help on using the browser.