О.о

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <osg/Node>
#include <osg/Group>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/PositionAttitudeTransform>
#include <osgGA/TrackballManipulator>
int main()
{
osgViewer::Viewer viewer;
osg::Group* root = new osg::Group();
osg::Geode* pyramidGeode = new osg::Geode();
osg::Geometry* pyramidGeometry = new osg::Geometry();
osg::Geode* crossGeode = new osg::Geode();
osg::Geometry* crossGeometry = new osg::Geometry();
//Associate the pyramid geometry with the pyramid geode
// Add the pyramid geode to the root node of the scene graph.
pyramidGeode->addDrawable(pyramidGeometry);
root->addChild(pyramidGeode);
crossGeode->addDrawable(crossGeometry);
root->addChild(crossGeode);
//Declare an array of vertices. Each vertex will be represented by
//a triple -- an instances of the vec3 class. An instance of
//osg::Vec3Array can be used to store these triples. Since
//osg::Vec3Array is derived from the STL vector class, we can use the
//push_back method to add array elements. Push back adds elements to
//the end of the vector, thus the index of first element entered is
//zero, the second entries index is 1, etc.
//Using a right-handed coordinate system with 'z' up, array
//elements zero..four below represent the 5 points required to create
//a simple pyramid.
osg::Vec3Array* pyramidVertices = new osg::Vec3Array;
pyramidVertices->push_back( osg::Vec3( 0, 0, 0) ); // front left
pyramidVertices->push_back( osg::Vec3(10, 0, 0) ); // front right
pyramidVertices->push_back( osg::Vec3(10,10, 0) ); // back right
pyramidVertices->push_back( osg::Vec3( 0,10, 0) ); // back left
pyramidVertices->push_back( osg::Vec3( 5, 5,10) ); // peak
float clen;
clen = 12.0;
osg::Vec3Array* crossVertices = new osg::Vec3Array;
crossVertices->push_back (osg::Vec3(-clen, 0.0, 0.0));
crossVertices->push_back (osg::Vec3( clen, 0.0, 0.0));
crossVertices->push_back (osg::Vec3( 0.0, 0.0, -clen));
crossVertices->push_back (osg::Vec3( 0.0, 0.0, clen));
//Associate this set of vertices with the geometry associated with the
//geode we added to the scene.
pyramidGeometry->setVertexArray( pyramidVertices );
crossGeometry->setVertexArray (crossVertices);
//Next, create a primitive set and add it to the pyramid geometry.
//Use the first four points of the pyramid to define the base using an
//instance of the DrawElementsUint class. Again this class is derived
//from the STL vector, so the push_back method will add elements in
//sequential order. To ensure proper backface cullling, vertices
//should be specified in counterclockwise order. The arguments for the
//constructor are the enumerated type for the primitive
//(same as the OpenGL primitive enumerated types), and the index in
//the vertex array to start from.
osg::DrawElementsUInt* pyramidBase =
new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
pyramidBase->push_back(3);
pyramidBase->push_back(2);
pyramidBase->push_back(1);
pyramidBase->push_back(0);
pyramidGeometry->addPrimitiveSet(pyramidBase);
osg::DrawElementsUInt* cross =
new osg::DrawElementsUInt(osg::PrimitiveSet::LINES, 0);
cross->push_back(3);
cross->push_back(2);
cross->push_back(1);
cross->push_back(0);
crossGeometry->addPrimitiveSet(cross);
//Repeat the same for each of the four sides. Again, vertices are
//specified in counter-clockwise order.
osg::DrawElementsUInt* pyramidFaceOne =
new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
pyramidFaceOne->push_back(0);
pyramidFaceOne->push_back(1);
pyramidFaceOne->push_back(4);
pyramidGeometry->addPrimitiveSet(pyramidFaceOne);
osg::DrawElementsUInt* pyramidFaceTwo =
new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
pyramidFaceTwo->push_back(1);
pyramidFaceTwo->push_back(2);
pyramidFaceTwo->push_back(4);
pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);
osg::DrawElementsUInt* pyramidFaceThree =
new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
pyramidFaceThree->push_back(2);
pyramidFaceThree->push_back(3);
pyramidFaceThree->push_back(4);
pyramidGeometry->addPrimitiveSet(pyramidFaceThree);
osg::DrawElementsUInt* pyramidFaceFour =
new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
pyramidFaceFour->push_back(3);
pyramidFaceFour->push_back(0);
pyramidFaceFour->push_back(4);
pyramidGeometry->addPrimitiveSet(pyramidFaceFour);
//Declare and load an array of Vec4 elements to store colors.
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 0 red
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) ); //index 1 green
colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); //index 2 blue
colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) ); //index 3 white
//Declare the variable that will match vertex array elements to color
//array elements. This vector should have the same number of elements
//as the number of vertices. This vector serves as a link between
//vertex arrays and color arrays. Entries in this index array
//coorespond to elements in the vertex array. Their values coorespond
//to the index in he color array. This same scheme would be followed
//if vertex array elements were matched with normal or texture
//coordinate arrays.
// Note that in this case, we are assigning 5 vertices to four
// colors. Vertex array element zero (bottom left) and four (peak)
// are both assigned to color array element zero (red).
osg::TemplateIndexArray
<unsigned int, osg::Array::UIntArrayType,4,4> *colorIndexArray;
colorIndexArray =
new osg::TemplateIndexArray<unsigned int, osg::Array::UIntArrayType,4,4>;
colorIndexArray->push_back(0); // vertex 0 assigned color array element 0
colorIndexArray->push_back(1); // vertex 1 assigned color array element 1
colorIndexArray->push_back(2); // vertex 2 assigned color array element 2
colorIndexArray->push_back(3); // vertex 3 assigned color array element 3
colorIndexArray->push_back(0); // vertex 4 assigned color array element 0
//The next step is to associate the array of colors with the geometry,
//assign the color indices created above to the geometry and set the
//binding mode to _PER_VERTEX.
pyramidGeometry->setColorArray(colors);
pyramidGeometry->setColorIndices(colorIndexArray);
pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
crossGeometry->setColorArray(colors);
crossGeometry->setColorIndices(colorIndexArray);
crossGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
//Now that we have created a geometry node and added it to the scene
//we can reuse this geometry. For example, if we wanted to put a
//second pyramid 15 units to the right of the first one, we could add
//this geode as the child of a transform node in our scene graph.
// Declare and initialize a transform node.
osg::PositionAttitudeTransform* pyramidTwoXForm =
new osg::PositionAttitudeTransform();
// Use the 'addChild' method of the osg::Group class to
// add the transform as a child of the root node and the
// pyramid node as a child of the transform.
root->addChild(pyramidTwoXForm);
pyramidTwoXForm->addChild(pyramidGeode);
// Declare and initialize a Vec3 instance to change the
// position of the model in the scene
osg::Vec3 pyramidTwoPosition(15,0,0);
pyramidTwoXForm->setPosition( pyramidTwoPosition );
//The final step is to set up and enter a simulation loop.
viewer.setSceneData( root );
//viewer.run();
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
viewer.realize();
while( !viewer.done() )
{
viewer.frame();
}
return 0;
}