root/OpenSceneGraph/trunk/examples/osgqfont/osgqfont.cpp @ 13482

Revision 13482, 19.9 kB (checked in by robert, 4 hours ago)

Added simple test script for osgUI's TabWidget?

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