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

Revision 6941, 18.0 kB (checked in by robert, 8 years ago)

From Martin Lavery and Robert Osfield, Updated examples to use a variation of the MIT License

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