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

Revision 13574, 16.2 kB (checked in by robert, 45 minutes ago)

From Mattias Helsing, "Seems I was only half right given what you asked for. CMP0017 only
says that modules that are found and ran from cmake modules dir should
prefer cmake-provided modules. find_package() and include() still look
in CMAKE_MODULE_PATH first.

After some investigating I've come up with a proposal examplified in
the attached FindGDAL.cmake script. It simply calls the cmake provided
FindGDAL.cmake if it exists and returns if it succeeds in finding GDAL
using that, otherwise continue with our local cmake code.
Pro: Wont clutter our root CMakeLists.txt
Con: If we begin to write more advanced Findxxx modules (using
COMPONENTS, REQUIRED etc.) we may have to revise this scheme.
"

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osglogo.
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 <osg/Geode>
20#include <osg/ShapeDrawable>
21#include <osg/Material>
22#include <osg/Texture2D>
23#include <osg/Geometry>
24#include <osg/MatrixTransform>
25#include <osg/PositionAttitudeTransform>
26#include <osg/BlendFunc>
27#include <osg/ClearNode>
28#include <osg/Version>
29
30#include <osgUtil/Tessellator>
31#include <osgUtil/CullVisitor>
32
33#include <osgText/Text>
34
35#include <osgGA/TrackballManipulator>
36
37#include <osgViewer/Viewer>
38
39#include <osgDB/ReadFile>
40
41#include <iostream>
42
43class MyBillboardTransform : public osg::PositionAttitudeTransform
44{
45    public:
46
47        MyBillboardTransform():
48            _axis(0.0f,0.0f,1.0f),
49            _normal(0.0f,-1.0f,0.0f)
50        {
51        }
52
53        bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
54        {
55            osg::Quat billboardRotation;
56            osgUtil::CullVisitor* cullvisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
57            if (cullvisitor)
58            {
59                osg::Vec3 eyevector = cullvisitor->getEyeLocal()-_position;
60                eyevector.normalize();
61
62                osg::Vec3 side = _axis^_normal;
63                side.normalize();
64
65                float angle = atan2(eyevector*_normal,eyevector*side);
66                billboardRotation.makeRotate(osg::PI_2-angle,_axis);
67
68            }
69
70            matrix.preMultTranslate(_position);
71            matrix.preMultRotate(billboardRotation);
72            matrix.preMultRotate(_attitude);
73            matrix.preMultTranslate(-_pivotPoint);
74            return true;
75        }
76
77
78
79        void setAxis(const osg::Vec3& axis) { _axis = axis; }
80
81        void setNormal(const osg::Vec3& normal) { _normal = normal; }
82
83    protected:
84
85        virtual ~MyBillboardTransform() {}
86
87        osg::Vec3 _axis;
88        osg::Vec3 _normal;
89};
90
91
92osg::Geometry* createWing(const osg::Vec3& left, const osg::Vec3& nose, const osg::Vec3& right,float chordRatio,const osg::Vec4& color)
93{
94    osg::Geometry* geom = new osg::Geometry;
95
96    osg::Vec3 normal = (nose-right)^(left-nose);
97    normal.normalize();
98
99    osg::Vec3 left_to_right = right-left;
100    osg::Vec3 mid = (right+left)*0.5f;
101    osg::Vec3 mid_to_nose = (nose-mid)*chordRatio*0.5f;
102
103    osg::Vec3Array* vertices = new osg::Vec3Array;
104    vertices->push_back(left);
105    //vertices->push_back(mid+mid_to_nose);
106
107    unsigned int noSteps = 40;
108    for(unsigned int i=1;i<noSteps;++i)
109    {
110        float ratio = (float)i/(float)noSteps;
111        vertices->push_back(left + left_to_right*ratio + mid_to_nose* (cosf((ratio-0.5f)*osg::PI*2.0f)+1.0f));
112    }
113
114    vertices->push_back(right);
115    vertices->push_back(nose);
116
117    geom->setVertexArray(vertices);
118
119
120    osg::Vec3Array* normals = new osg::Vec3Array;
121    normals->push_back(normal);
122    geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
123
124
125    osg::Vec4Array* colors = new osg::Vec4Array;
126    colors->push_back(color);
127    geom->setColorArray(colors, osg::Array::BIND_OVERALL);
128
129
130    geom->addPrimitiveSet(new osg::DrawArrays(GL_POLYGON,0,vertices->getNumElements()));
131
132    osgUtil::Tessellator tessellator;
133    tessellator.retessellatePolygons(*geom);
134
135    return geom;
136
137}
138
139osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label, const std::string&)
140{
141    osg::Geode* geode = new osg::Geode();
142
143    std::string font("fonts/arial.ttf");
144
145    osgText::Text* text = new  osgText::Text;
146
147    text->setFont(font);
148    text->setFontResolution(64,64);
149    text->setAlignment(osgText::Text::CENTER_CENTER);
150    text->setAxisAlignment(osgText::Text::XZ_PLANE);
151    text->setPosition(bb.center()-osg::Vec3(0.0f,0.0f,(bb.zMax()-bb.zMin())));
152    text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f));
153    text->setText(label);
154
155    geode->addDrawable( text );
156
157    return geode;
158}
159
160osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, const std::string& subscript)
161{
162    osg::Geode* geode = new osg::Geode();
163
164
165    osg::StateSet* stateset = geode->getOrCreateStateSet();
166    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
167
168
169    //std::string font("fonts/times.ttf");
170    std::string font("fonts/arial.ttf");
171
172    osgText::Text* text = new  osgText::Text;
173
174    text->setFont(font);
175    text->setFontResolution(110,120);
176    text->setAlignment(osgText::Text::RIGHT_CENTER);
177    text->setAxisAlignment(osgText::Text::XZ_PLANE);
178    text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f);
179    text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.1f));
180    //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour
181    text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour
182    text->setText(label);
183
184#if 1
185    text->setBackdropType(osgText::Text::OUTLINE);
186//   text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
187
188    text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET);
189//    text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER);
190//    text->setBackdropImplementation(osgText::Text::DEPTH_RANGE);
191//    text->setBackdropImplementation(osgText::Text::STENCIL_BUFFER);
192
193    text->setBackdropOffset(0.05f);
194    text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f));
195#endif
196
197
198#if 1
199    text->setColorGradientMode(osgText::Text::OVERALL);
200    osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f);
201    osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f);
202    text->setColorGradientCorners(lightblue, blue, blue, lightblue);
203#else
204    text->setColorGradientMode(osgText::Text::OVERALL);
205    osg::Vec4 light = osg::Vec4(0.0f, 1.0f, 1.0f, 1.0f);
206    osg::Vec4 dark = osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f);
207    text->setColorGradientCorners(light, dark, dark, light);
208//    text->setColorGradientCorners(dark, light, light, dark);
209#endif
210
211    geode->addDrawable( text );
212
213
214    if (!subscript.empty())
215    {
216        //osgText::Text* subscript = new  osgText::Text(new osgText::TextureFont(font,45));
217
218        osgText::Text* subscriptText = new osgText::Text;
219        subscriptText->setFont(font);
220        subscriptText->setText(subscript);
221        subscriptText->setAlignment(osgText::Text::RIGHT_CENTER);
222        subscriptText->setAxisAlignment(osgText::Text::XZ_PLANE);
223        subscriptText->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin())*4.3f,-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.6f));
224        subscriptText->setColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); // black
225
226        geode->addDrawable( subscriptText );
227    }
228
229    return geode;
230}
231
232osg:: Node* createGlobe(const osg::BoundingBox& bb,float ratio, const std::string& filename)
233{
234    osg::MatrixTransform* xform = new osg::MatrixTransform;
235    xform->setUpdateCallback(new osg::AnimationPathCallback(bb.center(),osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(10.0f)));
236
237    osg::Node* bluemarble = filename.empty() ? 0 : osgDB::readNodeFile(filename.c_str());
238    if (bluemarble)
239    {
240        const osg::BoundingSphere& bs = bluemarble->getBound();
241        float s = 1.2*bb.radius()/bs.radius();
242        osg::MatrixTransform* positioner = new osg::MatrixTransform;
243        positioner->setMatrix(osg::Matrix::translate(-bs.center())*osg::Matrix::scale(s,s,s)*osg::Matrix::translate(bb.center()));
244        positioner->addChild(bluemarble);
245
246        xform->addChild(positioner);
247    }
248    else
249    {
250
251        osg::Geode* geode = new osg::Geode();
252
253        osg::StateSet* stateset = geode->getOrCreateStateSet();
254
255        osg::Image* image = osgDB::readImageFile("Images/land_shallow_topo_2048.jpg");
256        if (image)
257        {
258            osg::Texture2D* texture = new osg::Texture2D;
259            texture->setImage(image);
260            texture->setMaxAnisotropy(8);
261            stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
262        }
263
264        osg::Material* material = new osg::Material;
265        stateset->setAttribute(material);
266
267        // the globe
268        geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(bb.center(),bb.radius()*ratio)));
269
270        xform->addChild(geode);
271    }
272
273    return xform;
274}
275
276osg:: Node* createBox(const osg::BoundingBox& bb,float chordRatio)
277{
278    osg::Geode* geode = new osg::Geode();
279
280    osg::Vec4 white(1.0f,1.0f,1.0f,1.0f);
281
282    // front faces.
283    geode->addDrawable(createWing(bb.corner(4),bb.corner(6),bb.corner(7),chordRatio,white));
284    geode->addDrawable(createWing(bb.corner(7),bb.corner(5),bb.corner(4),chordRatio,white));
285
286    geode->addDrawable(createWing(bb.corner(4),bb.corner(5),bb.corner(1),chordRatio,white));
287    geode->addDrawable(createWing(bb.corner(1),bb.corner(0),bb.corner(4),chordRatio,white));
288
289    geode->addDrawable(createWing(bb.corner(1),bb.corner(5),bb.corner(7),chordRatio,white));
290    geode->addDrawable(createWing(bb.corner(7),bb.corner(3),bb.corner(1),chordRatio,white));
291
292    // back faces
293    geode->addDrawable(createWing(bb.corner(2),bb.corner(0),bb.corner(1),chordRatio,white));
294    geode->addDrawable(createWing(bb.corner(1),bb.corner(3),bb.corner(2),chordRatio,white));
295
296    geode->addDrawable(createWing(bb.corner(2),bb.corner(3),bb.corner(7),chordRatio,white));
297    geode->addDrawable(createWing(bb.corner(7),bb.corner(6),bb.corner(2),chordRatio,white));
298
299    geode->addDrawable(createWing(bb.corner(2),bb.corner(6),bb.corner(4),chordRatio,white));
300    geode->addDrawable(createWing(bb.corner(4),bb.corner(0),bb.corner(2),chordRatio,white));
301
302    return geode;
303}
304
305osg:: Node* createBoxNo5(const osg::BoundingBox& bb,float chordRatio)
306{
307    osg::Geode* geode = new osg::Geode();
308
309    osg::Vec4 white(1.0f,1.0f,1.0f,1.0f);
310
311    // front faces.
312    geode->addDrawable(createWing(bb.corner(4),bb.corner(6),bb.corner(7),chordRatio,white));
313
314    geode->addDrawable(createWing(bb.corner(1),bb.corner(0),bb.corner(4),chordRatio,white));
315
316    geode->addDrawable(createWing(bb.corner(7),bb.corner(3),bb.corner(1),chordRatio,white));
317
318    // back faces
319    geode->addDrawable(createWing(bb.corner(2),bb.corner(0),bb.corner(1),chordRatio,white));
320    geode->addDrawable(createWing(bb.corner(1),bb.corner(3),bb.corner(2),chordRatio,white));
321
322    geode->addDrawable(createWing(bb.corner(2),bb.corner(3),bb.corner(7),chordRatio,white));
323    geode->addDrawable(createWing(bb.corner(7),bb.corner(6),bb.corner(2),chordRatio,white));
324
325    geode->addDrawable(createWing(bb.corner(2),bb.corner(6),bb.corner(4),chordRatio,white));
326    geode->addDrawable(createWing(bb.corner(4),bb.corner(0),bb.corner(2),chordRatio,white));
327
328    return geode;
329}
330
331osg:: Node* createBoxNo5No2(const osg::BoundingBox& bb,float chordRatio)
332{
333    osg::Geode* geode = new osg::Geode();
334
335//    osg::Vec4 red(1.0f,0.0f,0.0f,1.0f);
336//    osg::Vec4 green(0.0f,1.0f,0.0f,1.0f);
337//    osg::Vec4 blue(0.0f,0.0f,1.0f,1.0f);
338
339    osg::Vec4 red(1.0f,0.12f,0.06f,1.0f);
340    osg::Vec4 green(0.21f,0.48f,0.03f,1.0f);
341    osg::Vec4 blue(0.20f,0.45f,0.60f,1.0f);
342
343    // front faces.
344    geode->addDrawable(createWing(bb.corner(4),bb.corner(6),bb.corner(7),chordRatio,red));
345
346    geode->addDrawable(createWing(bb.corner(1),bb.corner(0),bb.corner(4),chordRatio,green));
347
348    geode->addDrawable(createWing(bb.corner(7),bb.corner(3),bb.corner(1),chordRatio,blue));
349
350    return geode;
351}
352
353osg:: Node* createBackdrop(const osg::Vec3& corner,const osg::Vec3& top,const osg::Vec3& right)
354{
355
356
357
358    osg::Geometry* geom = new osg::Geometry;
359
360    osg::Vec3 normal = (corner-top)^(right-corner);
361    normal.normalize();
362
363    osg::Vec3Array* vertices = new osg::Vec3Array;
364    vertices->push_back(top);
365    vertices->push_back(corner);
366
367    vertices->push_back(right);
368    vertices->push_back(right+(top-corner));
369
370    geom->setVertexArray(vertices);
371
372    osg::Vec3Array* normals = new osg::Vec3Array;
373    normals->push_back(normal);
374    geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
375
376    osg::Vec4Array* colors = new osg::Vec4Array;
377    colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
378    geom->setColorArray(colors, osg::Array::BIND_OVERALL);
379
380    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,vertices->getNumElements()));
381
382    osg::Geode* geode = new osg::Geode();
383    geode->addDrawable(geom);
384
385    return geode;
386}
387
388osg::Node* createLogo(const std::string& filename, const std::string& label, const std::string& subscript)
389{
390    osg::BoundingBox bb(osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(100.0f,100.0f,100.0f));
391    float chordRatio = 0.5f;
392    float sphereRatio = 0.6f;
393
394    // create a group to hold the whole model.
395    osg::Group* logo_group = new osg::Group;
396
397    osg::Quat r1,r2;
398    r1.makeRotate(-osg::inDegrees(45.0f),0.0f,0.0f,1.0f);
399    r2.makeRotate(osg::inDegrees(45.0f),1.0f,0.0f,0.0f);
400
401
402    MyBillboardTransform* xform = new MyBillboardTransform;
403    xform->setPivotPoint(bb.center());
404    xform->setPosition(bb.center());
405    xform->setAttitude(r1*r2);
406
407
408//     // create a transform to orientate the box and globe.
409//     osg::MatrixTransform* xform = new osg::MatrixTransform;
410//     xform->setDataVariance(osg::Object::STATIC);
411//     xform->setMatrix(osg::Matrix::translate(-bb.center())*
412//                      osg::Matrix::rotate(-osg::inDegrees(45.0f),0.0f,0.0f,1.0f)*
413//                      osg::Matrix::rotate(osg::inDegrees(45.0f),1.0f,0.0f,0.0f)*
414//                      osg::Matrix::translate(bb.center()));
415
416    // add the box and globe to it.
417    //xform->addChild(createBox(bb,chordRatio));
418    //xform->addChild(createBoxNo5(bb,chordRatio));
419    xform->addChild(createBoxNo5No2(bb,chordRatio));
420    // add the transform to the group.
421    logo_group->addChild(xform);
422
423    logo_group->addChild(createGlobe(bb,sphereRatio,filename));
424
425    // add the text to the group.
426    //group->addChild(createTextBelow(bb));
427    logo_group->addChild(createTextLeft(bb, label, subscript));
428
429
430    // create the backdrop to render the shadow to.
431    osg::Vec3 corner(-900.0f,150.0f,-100.0f);
432    osg::Vec3 top(0.0f,0.0f,300.0f); top += corner;
433    osg::Vec3 right(1100.0f,0.0f,0.0f); right += corner;
434
435
436//     osg::Group* backdrop = new osg::Group;
437//     backdrop->addChild(createBackdrop(corner,top,right));
438
439    osg::ClearNode* backdrop = new osg::ClearNode;
440    backdrop->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,0.0f));
441
442    //osg::Vec3 lightPosition(-500.0f,-2500.0f,500.0f);
443    //osg::Node* scene = createShadowedScene(logo_group,backdrop,lightPosition,0.0f,0);
444
445    osg::Group* scene = new osg::Group;
446
447    osg::StateSet* stateset = scene->getOrCreateStateSet();
448    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
449
450
451    scene->addChild(logo_group);
452    scene->addChild(backdrop);
453
454    return scene;
455}
456
457int main( int argc, char **argv )
458{
459    // use an ArgumentParser object to manage the program arguments.
460    osg::ArgumentParser arguments(&argc,argv);
461
462    osg::DisplaySettings::instance()->setMinimumNumAlphaBits(8);
463
464    // construct the viewer.
465    osgViewer::Viewer viewer;
466
467    // if user request help write it out to cout.
468    if (arguments.read("-h") || arguments.read("--help"))
469    {
470        arguments.getApplicationUsage()->write(std::cout);
471        return 1;
472    }
473
474    std::string label = "OpenSceneGraph";
475    std::string subscript = "";
476
477    bool showVersion = false;
478    while (arguments.read("--version")) { showVersion = true; }
479    if( showVersion )
480    {
481        label += " ";
482        label += osgGetVersion();
483    }
484
485    while (arguments.read("--label", label)) {}
486    while (arguments.read("--subscript", subscript)) {}
487
488    osg::ref_ptr<osg::Node> node;
489
490    if (arguments.argc()>1) node = createLogo(arguments[1], label, subscript);
491    else node = createLogo("", label, subscript);
492
493    // add model to viewer.
494    viewer.setSceneData( node.get() );
495
496    return viewer.run();
497}
Note: See TracBrowser for help on using the browser.