root/OpenSceneGraph/trunk/examples/osglogo/osglogo.cpp @ 1844

Revision 1844, 15.0 kB (checked in by robert, 12 years ago)

Added desciptions to all the demos.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/Geode>
2#include <osg/ShapeDrawable>
3#include <osg/Material>
4#include <osg/Texture2D>
5#include <osg/Geometry>
6#include <osg/MatrixTransform>
7#include <osg/PositionAttitudeTransform>
8#include <osg/BlendFunc>
9#include <osg/ClearNode>
10
11#include <osgUtil/Tesselator>
12#include <osgUtil/TransformCallback>
13#include <osgUtil/CullVisitor>
14
15#include <osgText/Text>
16
17#include <osgGA/TrackballManipulator>
18
19#include <osgProducer/Viewer>
20
21#include <osgDB/ReadFile>
22
23static bool s_ProfessionalServices = false;
24
25class MyBillboardTransform : public osg::PositionAttitudeTransform
26{
27    public:
28   
29        MyBillboardTransform():
30            _axis(0.0f,0.0f,1.0f),
31            _normal(0.0f,-1.0f,0.0f)
32        {
33        }
34       
35        bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
36        {
37            osg::Quat billboardRotation;
38            osgUtil::CullVisitor* cullvisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
39            if (cullvisitor)
40            {
41                osg::Vec3 eyevector = cullvisitor->getEyeLocal()-_position;
42                eyevector.normalize();
43
44                osg::Vec3 side = _axis^_normal;
45                side.normalize();
46
47                float angle = atan2(eyevector*_normal,eyevector*side);
48                billboardRotation.makeRotate(osg::PI_2-angle,_axis);
49
50            }
51
52
53            matrix.preMult(osg::Matrix::translate(-_pivotPoint)*
54                           osg::Matrix::rotate(_attitude)*
55                           osg::Matrix::rotate(billboardRotation)*
56                           osg::Matrix::translate(_position));
57            return true;
58        }
59
60
61       
62        void setAxis(const osg::Vec3& axis) { _axis = axis; }
63
64        void setNormal(const osg::Vec3& normal) { _normal = normal; }
65       
66    protected:
67   
68        virtual ~MyBillboardTransform() {}
69       
70        osg::Vec3 _axis;
71        osg::Vec3 _normal;
72};
73
74
75osg::Geometry* createWing(const osg::Vec3& left, const osg::Vec3& nose, const osg::Vec3& right,float chordRatio,const osg::Vec4& color)
76{
77    osg::Geometry* geom = new osg::Geometry;
78
79    osg::Vec3 normal = (nose-right)^(left-nose);
80    normal.normalize();
81
82    osg::Vec3 left_to_right = right-left;
83    osg::Vec3 mid = (right+left)*0.5f;
84    osg::Vec3 mid_to_nose = (nose-mid)*chordRatio*0.5f;
85   
86    osg::Vec3Array* vertices = new osg::Vec3Array;
87    vertices->push_back(left);
88    //vertices->push_back(mid+mid_to_nose);
89   
90    unsigned int noSteps = 40;
91    for(unsigned int i=1;i<noSteps;++i)
92    {
93        float ratio = (float)i/(float)noSteps;
94        vertices->push_back(left + left_to_right*ratio + mid_to_nose* (cosf((ratio-0.5f)*osg::PI*2.0f)+1.0f));
95    }
96   
97    vertices->push_back(right);
98    vertices->push_back(nose);
99
100    geom->setVertexArray(vertices);
101
102
103    osg::Vec3Array* normals = new osg::Vec3Array;
104    normals->push_back(normal);
105    geom->setNormalArray(normals);
106    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
107   
108   
109    osg::Vec4Array* colors = new osg::Vec4Array;
110    colors->push_back(color);
111    geom->setColorArray(colors);
112    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
113   
114
115    geom->addPrimitiveSet(new osg::DrawArrays(GL_POLYGON,0,vertices->getNumElements()));
116   
117    osgUtil::Tesselator tesselator;
118    tesselator.retesselatePolygons(*geom);
119
120    return geom;
121   
122}
123
124osg:: Node* createTextBelow(const osg::BoundingBox& bb)
125{
126    osg::Geode* geode = new osg::Geode();
127
128    std::string font("fonts/arial.ttf");
129
130    osgText::Text* text = new  osgText::Text;
131
132    text->setFont(font);
133    text->setFontSize(64,64);
134    text->setAlignment(osgText::Text::CENTER_CENTER);
135    text->setAxisAlignment(osgText::Text::XZ_PLANE);
136    text->setPosition(bb.center()-osg::Vec3(0.0f,0.0f,(bb.zMax()-bb.zMin())));
137    text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f));
138    text->setText("OpenSceneGraph");
139
140    geode->addDrawable( text );
141
142    return geode;
143}
144
145osg:: Node* createTextLeft(const osg::BoundingBox& bb)
146{
147    osg::Geode* geode = new osg::Geode();
148
149
150    osg::StateSet* stateset = geode->getOrCreateStateSet();
151    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
152
153
154    //std::string font("fonts/times.ttf");
155    std::string font("fonts/arial.ttf");
156
157    osgText::Text* text = new  osgText::Text;
158 
159    text->setFont(font);
160    text->setFontSize(120,120);
161    text->setAlignment(osgText::Text::RIGHT_CENTER);
162    text->setAxisAlignment(osgText::Text::XZ_PLANE);
163    text->setCharacterSize((bb.zMax()-bb.zMin())*0.8f);
164    text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.3f));
165    //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's orignal OSG colour
166    text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour
167    text->setText("OpenSceneGraph");
168
169    geode->addDrawable( text );
170
171
172    if (s_ProfessionalServices)
173    {
174        //osgText::Text* subscript = new  osgText::Text(new osgText::TextureFont(font,45));
175
176        osgText::Text* subscript = new osgText::Text;
177        subscript->setFont(font);
178        subscript->setText("Professional Services");
179        subscript->setAlignment(osgText::Text::RIGHT_CENTER);
180        subscript->setAxisAlignment(osgText::Text::XZ_PLANE);
181        subscript->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin())*3.5f,-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.6f));
182        subscript->setColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); // black
183
184        geode->addDrawable( subscript );
185    }
186       
187    return geode;
188}
189
190osg:: Node* createGlobe(const osg::BoundingBox& bb,float ratio)
191{
192    osg::Geode* geode = new osg::Geode();
193
194    osg::StateSet* stateset = geode->getOrCreateStateSet();
195
196    osg::Image* image = osgDB::readImageFile("Images/land_shallow_topo_2048.jpg");
197    if (image)
198    {
199        osg::Texture2D* texture = new osg::Texture2D;
200        texture->setImage(image);
201        texture->setMaxAnisotropy(8);
202        stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
203    }
204   
205    osg::Material* material = new osg::Material;
206    stateset->setAttribute(material);   
207   
208   
209    // the globe
210    geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(bb.center(),bb.radius()*ratio)));
211   
212   
213    osg::MatrixTransform* xform = new osg::MatrixTransform;
214    xform->setUpdateCallback(new osgUtil::TransformCallback(bb.center(),osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(30.0f)));
215    xform->addChild(geode);
216       
217    return xform;
218}
219
220osg:: Node* createBox(const osg::BoundingBox& bb,float chordRatio)
221{
222    osg::Geode* geode = new osg::Geode();
223
224    osg::Vec4 white(1.0f,1.0f,1.0f,1.0f);
225
226    // front faces.
227    geode->addDrawable(createWing(bb.corner(4),bb.corner(6),bb.corner(7),chordRatio,white));
228    geode->addDrawable(createWing(bb.corner(7),bb.corner(5),bb.corner(4),chordRatio,white));
229
230    geode->addDrawable(createWing(bb.corner(4),bb.corner(5),bb.corner(1),chordRatio,white));
231    geode->addDrawable(createWing(bb.corner(1),bb.corner(0),bb.corner(4),chordRatio,white));
232   
233    geode->addDrawable(createWing(bb.corner(1),bb.corner(5),bb.corner(7),chordRatio,white));
234    geode->addDrawable(createWing(bb.corner(7),bb.corner(3),bb.corner(1),chordRatio,white));
235
236    // back faces
237    geode->addDrawable(createWing(bb.corner(2),bb.corner(0),bb.corner(1),chordRatio,white));
238    geode->addDrawable(createWing(bb.corner(1),bb.corner(3),bb.corner(2),chordRatio,white));
239
240    geode->addDrawable(createWing(bb.corner(2),bb.corner(3),bb.corner(7),chordRatio,white));
241    geode->addDrawable(createWing(bb.corner(7),bb.corner(6),bb.corner(2),chordRatio,white));
242
243    geode->addDrawable(createWing(bb.corner(2),bb.corner(6),bb.corner(4),chordRatio,white));
244    geode->addDrawable(createWing(bb.corner(4),bb.corner(0),bb.corner(2),chordRatio,white));
245
246    return geode;
247}
248
249osg:: Node* createBoxNo5(const osg::BoundingBox& bb,float chordRatio)
250{
251    osg::Geode* geode = new osg::Geode();
252
253    osg::Vec4 white(1.0f,1.0f,1.0f,1.0f);
254
255    // front faces.
256    geode->addDrawable(createWing(bb.corner(4),bb.corner(6),bb.corner(7),chordRatio,white));
257
258    geode->addDrawable(createWing(bb.corner(1),bb.corner(0),bb.corner(4),chordRatio,white));
259   
260    geode->addDrawable(createWing(bb.corner(7),bb.corner(3),bb.corner(1),chordRatio,white));
261
262    // back faces
263    geode->addDrawable(createWing(bb.corner(2),bb.corner(0),bb.corner(1),chordRatio,white));
264    geode->addDrawable(createWing(bb.corner(1),bb.corner(3),bb.corner(2),chordRatio,white));
265
266    geode->addDrawable(createWing(bb.corner(2),bb.corner(3),bb.corner(7),chordRatio,white));
267    geode->addDrawable(createWing(bb.corner(7),bb.corner(6),bb.corner(2),chordRatio,white));
268
269    geode->addDrawable(createWing(bb.corner(2),bb.corner(6),bb.corner(4),chordRatio,white));
270    geode->addDrawable(createWing(bb.corner(4),bb.corner(0),bb.corner(2),chordRatio,white));
271
272    return geode;
273}
274
275osg:: Node* createBoxNo5No2(const osg::BoundingBox& bb,float chordRatio)
276{
277    osg::Geode* geode = new osg::Geode();
278
279//    osg::Vec4 red(1.0f,0.0f,0.0f,1.0f);
280//    osg::Vec4 green(0.0f,1.0f,0.0f,1.0f);
281//    osg::Vec4 blue(0.0f,0.0f,1.0f,1.0f);
282
283    osg::Vec4 red(1.0f,0.12f,0.06f,1.0f);
284    osg::Vec4 green(0.21f,0.48f,0.03f,1.0f);
285    osg::Vec4 blue(0.20f,0.45f,0.60f,1.0f);
286
287    // front faces.
288    geode->addDrawable(createWing(bb.corner(4),bb.corner(6),bb.corner(7),chordRatio,red));
289
290    geode->addDrawable(createWing(bb.corner(1),bb.corner(0),bb.corner(4),chordRatio,green));
291   
292    geode->addDrawable(createWing(bb.corner(7),bb.corner(3),bb.corner(1),chordRatio,blue));
293
294    return geode;
295}
296
297osg:: Node* createBackdrop(const osg::Vec3& corner,const osg::Vec3& top,const osg::Vec3& right)
298{
299
300
301
302    osg::Geometry* geom = new osg::Geometry;
303
304    osg::Vec3 normal = (corner-top)^(right-corner);
305    normal.normalize();
306
307    osg::Vec3Array* vertices = new osg::Vec3Array;
308    vertices->push_back(top);
309    vertices->push_back(corner);
310
311    vertices->push_back(right);
312    vertices->push_back(right+(top-corner));
313
314    geom->setVertexArray(vertices);
315
316    osg::Vec3Array* normals = new osg::Vec3Array;
317    normals->push_back(normal);
318    geom->setNormalArray(normals);
319    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
320
321    osg::Vec4Array* colors = new osg::Vec4Array;
322    colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
323    geom->setColorArray(colors);
324    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
325
326    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,vertices->getNumElements()));
327
328    osg::Geode* geode = new osg::Geode();
329    geode->addDrawable(geom);
330   
331    return geode;   
332}
333
334osg::Node* createLogo()
335{
336    osg::BoundingBox bb(osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(100.0f,100.0f,100.0f));
337    float chordRatio = 0.5f;
338    float sphereRatio = 0.6f;
339
340    // create a group to hold the whole model.
341    osg::Group* logo_group = new osg::Group;
342
343    osg::Quat r1,r2;
344    r1.makeRotate(-osg::inDegrees(45.0f),0.0f,0.0f,1.0f);
345    r2.makeRotate(osg::inDegrees(45.0f),1.0f,0.0f,0.0f);
346
347
348    MyBillboardTransform* xform = new MyBillboardTransform;
349    xform->setPivotPoint(bb.center());
350    xform->setPosition(bb.center());
351    xform->setAttitude(r1*r2);
352
353
354//     // create a transform to orientate the box and globe.
355//     osg::MatrixTransform* xform = new osg::MatrixTransform;
356//     xform->setDataVariance(osg::Object::STATIC);
357//     xform->setMatrix(osg::Matrix::translate(-bb.center())*
358//                      osg::Matrix::rotate(-osg::inDegrees(45.0f),0.0f,0.0f,1.0f)*
359//                      osg::Matrix::rotate(osg::inDegrees(45.0f),1.0f,0.0f,0.0f)*
360//                      osg::Matrix::translate(bb.center()));
361
362    // add the box and globe to it.
363    //xform->addChild(createBox(bb,chordRatio));
364    //xform->addChild(createBoxNo5(bb,chordRatio));
365    xform->addChild(createBoxNo5No2(bb,chordRatio));
366    // add the transform to the group.
367    logo_group->addChild(xform);
368
369    logo_group->addChild(createGlobe(bb,sphereRatio));
370
371    // add the text to the group.
372    //group->addChild(createTextBelow(bb));
373    logo_group->addChild(createTextLeft(bb));
374   
375   
376    // create the backdrop to render the shadow to.
377    osg::Vec3 corner(-900.0f,150.0f,-100.0f);
378    osg::Vec3 top(0.0f,0.0f,300.0f); top += corner;
379    osg::Vec3 right(1100.0f,0.0f,0.0f); right += corner;
380   
381   
382//     osg::Group* backdrop = new osg::Group;
383//     backdrop->addChild(createBackdrop(corner,top,right));
384
385    osg::ClearNode* backdrop = new osg::ClearNode;
386    backdrop->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
387
388    //osg::Vec3 lightPosition(-500.0f,-2500.0f,500.0f);
389    //osg::Node* scene = createShadowedScene(logo_group,backdrop,lightPosition,0.0f,0);
390
391    osg::Group* scene = new osg::Group;
392
393    osg::StateSet* stateset = scene->getOrCreateStateSet();
394    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
395
396
397    scene->addChild(logo_group);
398    scene->addChild(backdrop);
399
400    return scene;
401}
402
403int main( int argc, char **argv )
404{
405
406    // use an ArgumentParser object to manage the program arguments.
407    osg::ArgumentParser arguments(&argc,argv);
408
409    // set up the usage document, in case we need to print out how to use this program.
410    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates both text, animation and billboard via custom transform to create the OpenSceneGraph logo..");
411    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
412    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
413    arguments.getApplicationUsage()->addCommandLineOption("ps","Render the Professional Services logo");
414   
415    // construct the viewer.
416    osgProducer::Viewer viewer(arguments);
417
418    // set up the value with sensible default event handlers.
419    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
420
421    // get details on keyboard and mouse bindings used by the viewer.
422    viewer.getUsage(*arguments.getApplicationUsage());
423
424    // if user request help write it out to cout.
425    if (arguments.read("-h") || arguments.read("--help"))
426    {
427        arguments.getApplicationUsage()->write(std::cout);
428        return 1;
429    }
430   
431    while (arguments.read("ps")) s_ProfessionalServices = true;
432
433        // any option left unread are converted into errors to write out later.
434    arguments.reportRemainingOptionsAsUnrecognized();
435
436    // report any errors if they have occured when parsing the program aguments.
437    if (arguments.errors())
438    {
439        arguments.writeErrorMessages(std::cout);
440        return 1;
441    }
442   
443    osg::Node* node = createLogo();
444
445    // add model to viewer.
446    viewer.setSceneData( node );
447
448    // create the windows and run the threads.
449    viewer.realize();
450
451    while( !viewer.done() )
452    {
453        // wait for all cull and draw threads to complete.
454        viewer.sync();
455
456        // update the scene by traversing it with the the update visitor which will
457        // call all node update callbacks and animations.
458        viewer.update();
459         
460        // fire off the cull and draw traversals of the scene.
461        viewer.frame();
462       
463    }
464   
465    // wait for all cull and draw threads to complete before exit.
466    viewer.sync();
467
468    return 0;
469}
Note: See TracBrowser for help on using the browser.