Support/Tutorials/BasicGeometry: BasicGeometry.cpp

File BasicGeometry.cpp, 6.1 kB (added by robert, 6 years ago)
Line 
1#include <osg/Node>
2#include <osg/Group>
3#include <osg/Geode>
4#include <osg/Geometry>
5#include <osg/Texture2D>
6#include <osgDB/ReadFile> 
7#include <osgViewer/Viewer>
8#include <osg/PositionAttitudeTransform>
9#include <osgGA/TrackballManipulator>
10int main()
11{
12    osgViewer::Viewer viewer;
13    osg::Group* root = new osg::Group();
14    osg::Geode* pyramidGeode = new osg::Geode();
15    osg::Geometry* pyramidGeometry = new osg::Geometry();
16
17    //Associate the pyramid geometry with the pyramid geode
18    //   Add the pyramid geode to the root node of the scene graph.
19
20    pyramidGeode->addDrawable(pyramidGeometry);
21    root->addChild(pyramidGeode);
22
23    //Declare an array of vertices. Each vertex will be represented by
24    //a triple -- an instances of the vec3 class. An instance of
25    //osg::Vec3Array can be used to store these triples. Since
26    //osg::Vec3Array is derived from the STL vector class, we can use the
27    //push_back method to add array elements. Push back adds elements to
28    //the end of the vector, thus the index of first element entered is
29    //zero, the second entries index is 1, etc.
30    //Using a right-handed coordinate system with 'z' up, array
31    //elements zero..four below represent the 5 points required to create
32    //a simple pyramid.
33
34    osg::Vec3Array* pyramidVertices = new osg::Vec3Array;
35    pyramidVertices->push_back( osg::Vec3( 0, 0, 0) ); // front left
36    pyramidVertices->push_back( osg::Vec3(10, 0, 0) ); // front right
37    pyramidVertices->push_back( osg::Vec3(10,10, 0) ); // back right
38    pyramidVertices->push_back( osg::Vec3( 0,10, 0) ); // back left
39    pyramidVertices->push_back( osg::Vec3( 5, 5,10) ); // peak
40
41    //Associate this set of vertices with the geometry associated with the
42    //geode we added to the scene.
43
44    pyramidGeometry->setVertexArray( pyramidVertices );
45
46    //Next, create a primitive set and add it to the pyramid geometry.
47    //Use the first four points of the pyramid to define the base using an
48    //instance of the DrawElementsUint class. Again this class is derived
49    //from the STL vector, so the push_back method will add elements in
50    //sequential order. To ensure proper backface cullling, vertices
51    //should be specified in counterclockwise order. The arguments for the
52    //constructor are the enumerated type for the primitive
53    //(same as the OpenGL primitive enumerated types), and the index in
54    //the vertex array to start from.
55
56    osg::DrawElementsUInt* pyramidBase =
57        new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
58    pyramidBase->push_back(3);
59    pyramidBase->push_back(2);
60    pyramidBase->push_back(1);
61    pyramidBase->push_back(0);
62    pyramidGeometry->addPrimitiveSet(pyramidBase);
63
64    //Repeat the same for each of the four sides. Again, vertices are
65    //specified in counter-clockwise order.
66
67    osg::DrawElementsUInt* pyramidFaceOne =
68        new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
69    pyramidFaceOne->push_back(0);
70    pyramidFaceOne->push_back(1);
71    pyramidFaceOne->push_back(4);
72    pyramidGeometry->addPrimitiveSet(pyramidFaceOne);
73
74    osg::DrawElementsUInt* pyramidFaceTwo =
75        new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
76    pyramidFaceTwo->push_back(1);
77    pyramidFaceTwo->push_back(2);
78    pyramidFaceTwo->push_back(4);
79    pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);
80
81    osg::DrawElementsUInt* pyramidFaceThree =
82        new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
83    pyramidFaceThree->push_back(2);
84    pyramidFaceThree->push_back(3);
85    pyramidFaceThree->push_back(4);
86    pyramidGeometry->addPrimitiveSet(pyramidFaceThree);
87
88    osg::DrawElementsUInt* pyramidFaceFour =
89        new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
90    pyramidFaceFour->push_back(3);
91    pyramidFaceFour->push_back(0);
92    pyramidFaceFour->push_back(4);
93    pyramidGeometry->addPrimitiveSet(pyramidFaceFour);
94
95    //Declare and load an array of Vec4 elements to store colors.
96
97    osg::Vec4Array* colors = new osg::Vec4Array;
98    colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 0 red
99    colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) ); //index 1 green
100    colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); //index 2 blue
101    colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) ); //index 3 white
102    colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 4 red
103
104    //The next step is to associate the array of colors with the geometry,
105    //assign the color indices created above to the geometry and set the
106    //binding mode to _PER_VERTEX.
107
108    pyramidGeometry->setColorArray(colors);
109    pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
110
111    //Now that we have created a geometry node and added it to the scene
112    //we can reuse this geometry. For example, if we wanted to put a
113    //second pyramid 15 units to the right of the first one, we could add
114    //this geode as the child of a transform node in our scene graph.
115
116    // Declare and initialize a transform node.
117    osg::PositionAttitudeTransform* pyramidTwoXForm =
118        new osg::PositionAttitudeTransform();
119
120    // Use the 'addChild' method of the osg::Group class to
121    // add the transform as a child of the root node and the
122    // pyramid node as a child of the transform.
123
124    root->addChild(pyramidTwoXForm);
125    pyramidTwoXForm->addChild(pyramidGeode);
126
127    // Declare and initialize a Vec3 instance to change the
128    // position of the model in the scene
129
130    osg::Vec3 pyramidTwoPosition(15,0,0);
131    pyramidTwoXForm->setPosition( pyramidTwoPosition );
132
133    // switch off lighting as we haven't assigned any normals.
134    root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
135
136    //The final step is to set up and enter a simulation loop.
137
138    viewer.setSceneData( root );
139    //viewer.run();
140
141    viewer.setCameraManipulator(new osgGA::TrackballManipulator());
142    viewer.realize();
143
144    while( !viewer.done() )
145    {
146        viewer.frame();
147    }
148
149    return 0;
150}