1 // OpenSG Tutorial Example: Simple Geometry
3 // This example shows how to built a simple Geometry NodeCore.
5 // It also shows how to manipulate the geometry and what to watch out for. This
6 // is done in the display() function.
9 #ifdef OSG_BUILD_ACTIVE
12 #include <OSGConfig.h>
13 #include <OSGSimpleGeometry.h>
14 #include <OSGGeoProperties.h>
15 #include <OSGGLUTWindow.h>
16 #include <OSGSimpleSceneManager.h>
17 #include <OSGBaseFunctions.h>
18 #include <OSGTransform.h>
23 // the geometry node core
24 #include <OSGGeometry.h>
27 #include <OpenSG/OSGGLUT.h>
28 #include <OpenSG/OSGConfig.h>
29 #include <OpenSG/OSGSimpleGeometry.h>
30 #include <OpenSG/OSGGeoProperties.h>
31 #include <OpenSG/OSGGLUTWindow.h>
32 #include <OpenSG/OSGSimpleSceneManager.h>
33 #include <OpenSG/OSGBaseFunctions.h>
34 #include <OpenSG/OSGTransform.h>
35 #include <OpenSG/OSGGroup.h>
39 // the geometry node core
40 #include <OpenSG/OSGGeometry.h>
43 // The pointer to the transformation
44 OSG::TransformRefPtr trans
;
46 // The pointer to the geometry core
47 OSG::GeometryRefPtr geo
;
50 // The SimpleSceneManager to manage simple applications
51 OSG::SimpleSceneManagerRefPtr mgr
;
53 // forward declaration so we can have the interesting stuff upfront
54 int setupGLUT( int *argc
, char *argv
[] );
56 // Initialize GLUT & OpenSG and set up the scene
57 int main(int argc
, char **argv
)
60 OSG::osgInit(argc
,argv
);
63 int winid
= setupGLUT(&argc
, argv
);
65 // open a new scope, because the pointers below should go out of scope
66 // before entering glutMainLoop.
67 // Otherwise OpenSG will complain about objects being alive after shutdown.
69 // the connection between GLUT and OpenSG
70 OSG::GLUTWindowRefPtr gwin
= OSG::GLUTWindow::create();
71 gwin
->setGlutId(winid
);
77 Geometry data in OpenSG is stored in several separate vectors.
79 These vectors are not a direct part of the Geometry Core but
80 rather split up into multiple separate classes.
82 These classes, the GeoProperties, contain a single field containg
83 their values, which can be accessed directly, see the docs for
84 GeoProperty for the whole interface.
88 The first part: the primtive types.
89 These are taken from OpenGL, any values that can be passed to
90 glBegin(); are legal. Different types can be freely mixed.
92 OSG::GeoUInt8PropertyRefPtr type
= OSG::GeoUInt8Property::create();
93 type
->addValue(GL_POLYGON
);
94 type
->addValue(GL_TRIANGLES
);
95 type
->addValue(GL_QUADS
);
98 The second part: the primtive lengths.
99 These define the number of vertices to be passed to OpenGL for each
100 primitive. Thus there have to be at least as many entries as in the
103 OSG::GeoUInt32PropertyRefPtr lens
= OSG::GeoUInt32Property::create();
109 The third part: the vertex positions.
111 OpenSG uses different types for vectors and points.
113 Points (e.g. Pnt3f) are just positions in space, they have a limited
114 set of operations they can handle. Vectors (e.g. Vec3f) are the more
117 OSG::GeoPnt3fPropertyRefPtr pnts
= OSG::GeoPnt3fProperty::create();
118 // the 4 points of the polygon
119 pnts
->addValue(OSG::Pnt3f(-1, -1, -1));
120 pnts
->addValue(OSG::Pnt3f(-1, -1, 1));
121 pnts
->addValue(OSG::Pnt3f( 1, -1, 1));
122 pnts
->addValue(OSG::Pnt3f( 1, -1, -1));
124 // the 6 points of the two triangles
125 pnts
->addValue(OSG::Pnt3f( 1, 0, -1));
126 pnts
->addValue(OSG::Pnt3f(-1, 0, -1));
127 pnts
->addValue(OSG::Pnt3f( 0, 1, -1));
129 pnts
->addValue(OSG::Pnt3f(-1, 0, 1));
130 pnts
->addValue(OSG::Pnt3f( 1, 0, 1));
131 pnts
->addValue(OSG::Pnt3f( 0, 1, 1));
133 // the 8 points of the two quads
134 pnts
->addValue(OSG::Pnt3f(-1, -1, 1));
135 pnts
->addValue(OSG::Pnt3f( 1, -1, 1));
136 pnts
->addValue(OSG::Pnt3f( 1, 0, 1));
137 pnts
->addValue(OSG::Pnt3f(-1, 0, 1));
139 pnts
->addValue(OSG::Pnt3f( 1, -1, -1));
140 pnts
->addValue(OSG::Pnt3f(-1, -1, -1));
141 pnts
->addValue(OSG::Pnt3f(-1, 0, -1));
142 pnts
->addValue(OSG::Pnt3f( 1, 0, -1));
145 Put it all together into a Geometry NodeCore.
147 geo
= OSG::Geometry::create();
148 geo
->setTypes (type
);
149 geo
->setLengths (lens
);
150 geo
->setPositions(pnts
);
152 // assign a material to the geometry to make it visible. The details
153 // of materials are defined later.
154 geo
->setMaterial(OSG::getDefaultUnlitMaterial());
156 // put the geometry core into a node
157 OSG::NodeRefPtr n
= OSG::Node::create();
160 // add a transformation to make it move
161 OSG::NodeRefPtr scene
= OSG::Node::create();
162 trans
= OSG::Transform::create();
163 scene
->setCore(trans
);
166 OSG::commitChanges();
168 // create the SimpleSceneManager helper
169 mgr
= OSG::SimpleSceneManager::create();
171 // tell the manager what to manage
172 mgr
->setWindow(gwin
);
173 mgr
->setRoot (scene
);
175 // show the whole scene
186 // GLUT callback functions
194 OSG::Real32 t
= glutGet(GLUT_ELAPSED_TIME
);
196 m
.setTransform(OSG::Quaternion( OSG::Vec3f(0,1,0),
199 // set the transform's matrix
203 Manipulate the geometry.
205 The OpenSG geometry structure is pretty flexible.
207 The disadvantage of all this flexibility is that it can be hard to
208 write generic tools, as pretty much all the used types can be one of a
211 To simplify that, every kind of GeoProperty has a generic type, e.g.
212 the generic type for positions is Pnt3f, for colors it's Color3f.
214 No matter the internal data representation looks like, all
215 GeoProperties have the generic interface. As does the abstract parent
216 class of every kind of property. Thus it's possible to access the data
217 of an arbitrary geometry using the generic interface.
220 // note that this is the abstract parent class, it doesn't have a specific
222 OSG::GeoVectorProperty
*pos
= geo
->getPositions();
224 for(OSG::UInt32 i
= 0; i
< pos
->size(); i
++)
229 p
[0] += OSG::osgSin(t
/ 3000) * p
[0] / 100;
230 p
[1] += OSG::osgSin(t
/ 3000) * p
[1] / 100;
231 p
[2] += OSG::osgSin(t
/ 3000) * p
[2] / 100;
236 OSG::commitChanges();
241 // react to size changes
242 void reshape(int w
, int h
)
248 // react to mouse button presses
249 void mouse(int button
, int state
, int x
, int y
)
252 mgr
->mouseButtonRelease(button
, x
, y
);
254 mgr
->mouseButtonPress(button
, x
, y
);
259 // react to mouse motions with pressed buttons
260 void motion(int x
, int y
)
262 mgr
->mouseMove(x
, y
);
267 void keyboard(unsigned char k
, int x
, int y
)
273 // clean up global variables
285 mgr
->setStatistics(!mgr
->getStatistics());
291 // setup the GLUT library which handles the windows for us
292 int setupGLUT(int *argc
, char *argv
[])
294 glutInit(argc
, argv
);
295 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
297 int winid
= glutCreateWindow("OpenSG");
299 glutReshapeFunc(reshape
);
300 glutDisplayFunc(display
);
301 glutMouseFunc(mouse
);
302 glutMotionFunc(motion
);
303 glutKeyboardFunc(keyboard
);
305 // call the redraw function whenever there's nothing else to do
306 glutIdleFunc(display
);