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

Revision 1651, 17.5 kB (checked in by robert, 11 years ago)

Updates to the GLUT and Producer text demo.

Fix to text to better handle unsetting of vertex arrays.

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