1 // OpenSG NURBS example: testRationalSurfaceRender.cpp
3 // Shows how to render rational NURBS surfaces
5 // In OpenSG, similarly to OpenGL and OpenInventor rational
6 // control points are expected in homogenious coordinates
7 // (as opposed to Euclidian coordinates) that is a rational
8 // control point is [xw yw zw w] for surfaces, and
9 // [xw yw w] for trimming curves where [x y z] (or [x y]) are
10 // the Euclidian coordinates of the control point.
12 // Although this is not enforced, negative weights are
13 // not allowed, if a surface/curve has negative weights
14 // the behaviour of the tessellator is undefined.
16 // Zero weights are allowed, but only for inner control points.
17 // In other words, the first and last control points of a trimming
18 // curve (or the four corner control points of a surface) must all
19 // have positive weights.
21 // Press the keys '1', '2' and '3' in order to switch between
22 // the different example objects. Note that especially in the
23 // case of the torus and the teapot, tessellation takes some
24 // time so expect some delay when switching to the objects for
28 #include "OSGConfig.h"
29 #include "OSGSimpleSceneManager.h"
30 #include "OSGSimpleMaterial.h"
31 #include "OSGGLUTWindow.h"
32 #include "OSGSolidBackground.h"
33 #include "OSGSurface.h"
34 #include "OSGSwitch.h"
35 #include "OSGCoredNodePtr.h"
36 #include "OSGSceneFileHandler.h"
39 OSG::SimpleSceneManagerRefPtr g_mgr
= NULL
;
40 OSG::NodeRefPtr g_scene
= NULL
;
41 std::vector
<OSG::Surface
*> g_teapotSurfaces
;
42 std::vector
<OSG::Surface
*> g_torusSurfaces
;
43 std::vector
<OSG::Surface
*> g_cylinderSurfaces
;
44 std::vector
<OSG::Surface
*> *g_currentSurfaces
;
54 // react to size changes
55 void reshape(int w
, int h
)
61 // react to mouse button presses
62 void mouse(int button
, int state
, int x
, int y
)
65 g_mgr
->mouseButtonRelease(button
, x
, y
);
67 g_mgr
->mouseButtonPress(button
, x
, y
);
72 // react to mouse motions with pressed buttons
73 void motion(int x
, int y
)
75 g_mgr
->mouseMove(x
, y
);
80 void setModel(OSG::Int32 which
)
82 OSG::Switch
*s
= dynamic_cast<OSG::Switch
*>(g_scene
->getCore());
87 case 0: g_currentSurfaces
= &g_teapotSurfaces
;
90 case 1: g_currentSurfaces
= &g_torusSurfaces
;
93 case 2: g_currentSurfaces
= &g_cylinderSurfaces
;
96 default: std::cerr
<< "setModel [" << which
<< "] out of range."
106 void keyboard(unsigned char k
, int, int)
110 case 27: g_mgr
= NULL
;
115 glPolygonMode( GL_FRONT_AND_BACK
, GL_POINT
);
116 std::cerr
<< "PolygonMode: Point." << std::endl
;
118 case 'x': glPolygonMode( GL_FRONT_AND_BACK
, GL_LINE
);
119 std::cerr
<< "PolygonMode: Line." << std::endl
;
121 case 'c': glPolygonMode( GL_FRONT_AND_BACK
, GL_FILL
);
122 std::cerr
<< "PolygonMode: Fill." << std::endl
;
124 case '1': std::cerr
<<"Model: teapot."<<std::endl
;
127 case '2': std::cerr
<<"Model: torus."<<std::endl
;
130 case '3': std::cerr
<<"Model: trimmed cylinder."<<std::endl
;
133 case 'o': OSG::SceneFileHandler::the()->write(g_scene
, "out.osb");
136 case 'f': for(OSG::UInt32 i
= 0; i
< g_currentSurfaces
->size(); ++i
)
138 g_currentSurfaces
->at(i
)->setError(
139 2 * g_currentSurfaces
->at(i
)->getError());
143 case 'g': for(OSG::UInt32 i
= 0; i
< g_currentSurfaces
->size(); ++i
)
145 g_currentSurfaces
->at(i
)->setError(
146 g_currentSurfaces
->at(i
)->getError() / 2);
154 // Helper function to create an untrimmed rational OSG::Surface Core+Node
155 // from the controlpoints, dimensions in U & V,
156 // knotvectors in U & V and the desired error and material.
157 OSG::NodeTransitPtr
makeSurface(const int numcps
, const float xyzw
[][4],
158 const int dimU
, const int dimV
,
159 const int numknotsU
, const float *knotsU
,
160 const int numknotsV
, const float *knotsV
,
161 const float error
, OSG::Material
*mat
)
163 OSG::SurfaceRefPtr surface
;
164 OSG::NodeTransitPtr ret
=
165 OSG::makeCoredNode
<OSG::Surface
>(&surface
);
166 OSG::GeoPnt4fPropertyRefPtr cps
= OSG::GeoPnt4fProperty::create();
170 for (i
= 0; i
< numcps
; ++i
)
172 cps
->editField().push_back(OSG::Pnt4f(xyzw
[i
][0], xyzw
[i
][1],
173 xyzw
[i
][2], xyzw
[i
][3]));
176 // let's clear the trimming
177 surface
->removeCurves();
178 // set up dimensions and knot vectors:
179 surface
->setDimU( dimU
);
180 surface
->setDimV( dimV
);
181 surface
->editMFKnotsU()->clear();
182 for (i
= 0; i
< numknotsU
; ++i
)
184 surface
->editMFKnotsU()->push_back(knotsU
[i
]);
187 surface
->editMFKnotsV()->clear();
188 for (i
= 0; i
< numknotsV
; ++i
)
190 surface
->editMFKnotsV()->push_back(knotsV
[i
]);
192 // set control points
193 surface
->setControlPoints(cps
);
195 surface
->setError(error
);
196 // and finally set the material
197 surface
->setMaterial(mat
);
202 // Helper function to add a polynomial trimcurve to an OSG::Surface NodeCore
203 void addTrimCurve(OSG::Surface
*surf
, const int numcps
, const float xy
[][2],
204 const int dim
, const int numknots
, const float *knots
,
205 bool startnewloop
= false)
207 std::vector
<OSG::Real64
> knotv
;
208 std::vector
<OSG::Pnt2f
> cps
;
210 for (i
= 0; i
< numcps
; ++i
)
212 cps
.push_back(OSG::Pnt2f(xy
[i
][0], xy
[i
][1]));
214 for (i
= 0; i
< numknots
; ++i
)
216 knotv
.push_back(knots
[i
]);
219 surf
->addCurve(dim
, knotv
, cps
, startnewloop
);
222 // Helper function to add a rational trimcurve to an OSG::Surface NodeCore
223 void addTrimCurve(OSG::Surface
*surf
, const int numcps
, const float xyw
[][3],
224 const int dim
, const int numknots
, const float *knots
,
225 bool startnewloop
= false)
227 std::vector
<OSG::Real64
> knotv
;
228 std::vector
<OSG::Pnt3f
> cps
;
230 for (i
= 0; i
< numcps
; ++i
)
232 cps
.push_back(OSG::Pnt3f(xyw
[i
][0], xyw
[i
][1], xyw
[i
][2]));
234 for (i
= 0; i
< numknots
; ++i
)
236 knotv
.push_back(knots
[i
]);
239 surf
->addCurve(dim
, knotv
, cps
, startnewloop
);
243 // This function creates the classic Utah teapot from 4 NURBS
244 // surfaces: one surface each for the lid, body, handle and spout.
245 // The "classic" representation is using 18 rational Bezier patches,
246 // but in order to show the construction of more complex surfaces
247 // these have been combined into as few NURBS surfaces as possible.
248 OSG::NodeTransitPtr
makeTeapot(void)
250 OSG::SimpleMaterialRefPtr teapotmat
= OSG::SimpleMaterial::create();
252 teapotmat
->setDiffuse( OSG::Color3f(0.8, 0.8, 0.8));
253 teapotmat
->setAmbient( OSG::Color3f(0.2, 0.2, 0.2));
254 teapotmat
->setEmission( OSG::Color3f(0.02, 0.02, 0.02) );
255 teapotmat
->setSpecular( OSG::Color3f(0.78, 0.78, 0.78) );
256 teapotmat
->setShininess( 128 );
258 OSG::NodeTransitPtr teapotroot
= OSG::makeCoredNode
<OSG::Group
>();
259 float knots11
[11] = {0, 0, 0, 0, 0.5, 0.5, 0.5, 1, 1, 1, 1};
260 float knots14
[14] = {0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3};
261 float knots_circle
[8] = {0, 0, 0, 0.5, 0.5, 1, 1, 1};
262 float lidcps
[35][4] = {
263 { 0.0000, 4.0000, 0.0000, 1.0000},
264 { 0.0000, 4.0000, 0.8000, 1.0000},
265 { 0.0000, 3.6000, 0.0000, 1.0000},
266 { 0.0000, 3.4000, 0.2000, 1.0000},
267 { 0.0000, 3.2000, 0.4000, 1.0000},
268 { 0.0000, 3.2000, 1.3000, 1.0000},
269 { 0.0000, 3.0000, 1.3000, 1.0000},
271 {-0.0000, 0.0000, 0.0000, 0.0000},
272 {-0.8000, 0.0000, 0.0000, 0.0000},
273 {-0.0000, 0.0000, 0.0000, 0.0000},
274 {-0.2000, 0.0000, 0.0000, 0.0000},
275 {-0.4000, 0.0000, 0.0000, 0.0000},
276 {-1.3000, 0.0000, 0.0000, 0.0000},
277 {-1.3000, 0.0000, 0.0000, 0.0000},
279 { 0.0000, 4.0000,-0.0000, 1.0000},
280 { 0.0000, 4.0000,-0.8000, 1.0000},
281 { 0.0000, 3.6000,-0.0000, 1.0000},
282 { 0.0000, 3.4000,-0.2000, 1.0000},
283 { 0.0000, 3.2000,-0.4000, 1.0000},
284 { 0.0000, 3.2000,-1.3000, 1.0000},
285 { 0.0000, 3.0000,-1.3000, 1.0000},
287 { 0.0000, 0.0000, 0.0000, 0.0000},
288 { 0.8000, 0.0000, 0.0000, 0.0000},
289 { 0.0000, 0.0000, 0.0000, 0.0000},
290 { 0.2000, 0.0000, 0.0000, 0.0000},
291 { 0.4000, 0.0000, 0.0000, 0.0000},
292 { 1.3000, 0.0000, 0.0000, 0.0000},
293 { 1.3000, 0.0000, 0.0000, 0.0000},
295 { 0.0000, 4.0000, 0.0000, 1.0000},
296 { 0.0000, 4.0000, 0.8000, 1.0000},
297 { 0.0000, 3.6000, 0.0000, 1.0000},
298 { 0.0000, 3.4000, 0.2000, 1.0000},
299 { 0.0000, 3.2000, 0.4000, 1.0000},
300 { 0.0000, 3.2000, 1.3000, 1.0000},
301 { 0.0000, 3.0000, 1.3000, 1.0000},
303 OSG::NodeRefPtr lid
= makeSurface(35, lidcps
, 2, 3, 8, knots_circle
,
304 11, knots11
, 0.005, teapotmat
);
306 g_teapotSurfaces
.push_back(dynamic_cast<OSG::Surface
*>(lid
->getCore()));
308 float bodycps
[50][4] = {
309 { 0.0000, 3.0000, 1.4000, 1.0000},
310 { 0.0000, 3.1750, 1.3375, 1.0000},
311 { 0.0000, 3.1750, 1.4375, 1.0000},
312 { 0.0000, 3.0000, 1.5000, 1.0000},
313 { 0.0000, 2.3000, 1.7500, 1.0000},
314 { 0.0000, 1.6000, 2.0000, 1.0000},
315 { 0.0000, 1.0000, 2.0000, 1.0000},
316 { 0.0000, 0.4000, 2.0000, 1.0000},
317 { 0.0000, 0.2000, 1.5000, 1.0000},
318 { 0.0000, 0.0000, 1.5000, 1.0000},
320 {-1.4000, 0.0000, 0.0000, 0.0000},
321 {-1.3375, 0.0000, 0.0000, 0.0000},
322 {-1.4375, 0.0000, 0.0000, 0.0000},
323 {-1.5000, 0.0000, 0.0000, 0.0000},
324 {-1.7500, 0.0000, 0.0000, 0.0000},
325 {-2.0000, 0.0000, 0.0000, 0.0000},
326 {-2.0000, 0.0000, 0.0000, 0.0000},
327 {-2.0000, 0.0000, 0.0000, 0.0000},
328 {-1.5000, 0.0000, 0.0000, 0.0000},
329 {-1.5000, 0.0000, 0.0000, 0.0000},
331 { 0.0000, 3.0000,-1.4000, 1.0000},
332 { 0.0000, 3.1750,-1.3375, 1.0000},
333 { 0.0000, 3.1750,-1.4375, 1.0000},
334 { 0.0000, 3.0000,-1.5000, 1.0000},
335 { 0.0000, 2.3000,-1.7500, 1.0000},
336 { 0.0000, 1.6000,-2.0000, 1.0000},
337 { 0.0000, 1.0000,-2.0000, 1.0000},
338 { 0.0000, 0.4000,-2.0500, 1.0000},
339 { 0.0000, 0.2000,-1.5000, 1.0000},
340 { 0.0000, 0.0000,-1.5000, 1.0000},
342 { 1.4000, 0.0000, 0.0000, 0.0000},
343 { 1.3375, 0.0000, 0.0000, 0.0000},
344 { 1.4375, 0.0000, 0.0000, 0.0000},
345 { 1.5000, 0.0000, 0.0000, 0.0000},
346 { 1.7500, 0.0000, 0.0000, 0.0000},
347 { 2.0000, 0.0000, 0.0000, 0.0000},
348 { 2.0000, 0.0000, 0.0000, 0.0000},
349 { 2.0000, 0.0000, 0.0000, 0.0000},
350 { 1.5000, 0.0000, 0.0000, 0.0000},
351 { 1.5000, 0.0000, 0.0000, 0.0000},
353 { 0.0000, 3.0000, 1.4000, 1.0000},
354 { 0.0000, 3.1750, 1.3375, 1.0000},
355 { 0.0000, 3.1750, 1.4375, 1.0000},
356 { 0.0000, 3.0000, 1.5000, 1.0000},
357 { 0.0000, 2.3000, 1.7500, 1.0000},
358 { 0.0000, 1.6000, 2.0000, 1.0000},
359 { 0.0000, 1.0000, 2.0000, 1.0000},
360 { 0.0000, 0.4000, 2.0000, 1.0000},
361 { 0.0000, 0.2000, 1.5000, 1.0000},
362 { 0.0000, 0.0000, 1.5000, 1.0000},
365 OSG::NodeRefPtr body
= makeSurface(50, bodycps
, 2, 3, 8, knots_circle
,
366 14, knots14
, 0.005, teapotmat
);
368 g_teapotSurfaces
.push_back(dynamic_cast<OSG::Surface
*>(body
->getCore()));
370 float handlecps
[35][4] = {
371 { 1.5000, 2.8000, 0.0000, 1.0000},
372 { 2.5000, 2.8000, 0.0000, 1.0000},
373 { 3.0000, 2.8000, 0.0000, 1.0000},
374 { 3.0000, 2.2000, 0.0000, 1.0000},
375 { 3.0000, 1.6000, 0.0000, 1.0000},
376 { 2.6500, 1.0500, 0.0000, 1.0000},
377 { 1.9000, 0.6000, 0.0000, 1.0000},
379 { 0.0000, 0.0000, 0.3000, 0.0000},
380 { 0.0000, 0.0000, 0.3000, 0.0000},
381 { 0.0000, 0.0000, 0.3000, 0.0000},
382 { 0.0000, 0.0000, 0.3000, 0.0000},
383 { 0.0000, 0.0000, 0.3000, 0.0000},
384 { 0.0000, 0.0000, 0.3000, 0.0000},
385 { 0.0000, 0.0000, 0.3000, 0.0000},
387 { 1.6000, 2.5000, 0.0000, 1.0000},
388 { 2.3000, 2.5000, 0.0000, 1.0000},
389 { 2.7000, 2.5000, 0.0000, 1.0000},
390 { 2.7000, 2.2000, 0.0000, 1.0000},
391 { 2.7000, 1.9000, 0.0000, 1.0000},
392 { 2.5000, 1.5000, 0.0000, 1.0000},
393 { 2.0000, 1.0000, 0.0000, 1.0000},
395 { 0.0000, 0.0000,-0.3000, 0.0000},
396 { 0.0000, 0.0000,-0.3000, 0.0000},
397 { 0.0000, 0.0000,-0.3000, 0.0000},
398 { 0.0000, 0.0000,-0.3000, 0.0000},
399 { 0.0000, 0.0000,-0.3000, 0.0000},
400 { 0.0000, 0.0000,-0.3000, 0.0000},
401 { 0.0000, 0.0000,-0.3000, 0.0000},
403 { 1.5000, 2.8000, 0.0000, 1.0000},
404 { 2.5000, 2.8000, 0.0000, 1.0000},
405 { 3.0000, 2.8000, 0.0000, 1.0000},
406 { 3.0000, 2.2000, 0.0000, 1.0000},
407 { 3.0000, 1.6000, 0.0000, 1.0000},
408 { 2.6500, 1.0500, 0.0000, 1.0000},
409 { 1.9000, 0.6000, 0.0000, 1.0000},
412 OSG::NodeRefPtr handle
= makeSurface(35, handlecps
, 2, 3, 8, knots_circle
,
413 11, knots11
, 0.005, teapotmat
);
415 g_teapotSurfaces
.push_back(dynamic_cast<OSG::Surface
*>(handle
->getCore()));
417 float spoutcps
[35][4] = {
418 {-1.7000, 0.6000, 0.0000, 1.0000},
419 {-3.1000, 0.9000, 0.0000, 1.0000},
420 {-2.4000, 2.6000, 0.0000, 1.0000},
421 {-3.3000, 3.0000, 0.0000, 1.0000},
422 {-3.5250, 3.1250, 0.0000, 1.0000},
423 {-3.4500, 3.1500, 0.0000, 1.0000},
424 {-3.2000, 3.0000, 0.0000, 1.0000},
426 { 0.0000, 0.0000, 0.6600, 0.0000},
427 { 0.0000, 0.0000, 0.6600, 0.0000},
428 { 0.0000, 0.0000, 0.2500, 0.0000},
429 { 0.0000, 0.0000, 0.2500, 0.0000},
430 { 0.0000, 0.0000, 0.2500, 0.0000},
431 { 0.0000, 0.0000, 0.1500, 0.0000},
432 { 0.0000, 0.0000, 0.1500, 0.0000},
434 {-1.7000, 1.7000, 0.0000, 1.0000},
435 {-2.6000, 1.7000, 0.0000, 1.0000},
436 {-2.3000, 2.6000, 0.0000, 1.0000},
437 {-2.7000, 3.0000, 0.0000, 1.0000},
438 {-2.8000, 3.1000, 0.0000, 1.0000},
439 {-2.9000, 3.1000, 0.0000, 1.0000},
440 {-2.8000, 3.0000, 0.0000, 1.0000},
442 { 0.0000, 0.0000,-0.6600, 0.0000},
443 { 0.0000, 0.0000,-0.6600, 0.0000},
444 { 0.0000, 0.0000,-0.2500, 0.0000},
445 { 0.0000, 0.0000,-0.2500, 0.0000},
446 { 0.0000, 0.0000,-0.2500, 0.0000},
447 { 0.0000, 0.0000,-0.1500, 0.0000},
448 { 0.0000, 0.0000,-0.1500, 0.0000},
450 {-1.7000, 0.6000, 0.0000, 1.0000},
451 {-3.1000, 0.9000, 0.0000, 1.0000},
452 {-2.4000, 2.6000, 0.0000, 1.0000},
453 {-3.3000, 3.0000, 0.0000, 1.0000},
454 {-3.5250, 3.1250, 0.0000, 1.0000},
455 {-3.4500, 3.1500, 0.0000, 1.0000},
456 {-3.2000, 3.0000, 0.0000, 1.0000},
458 OSG::NodeRefPtr spout
= makeSurface(35, spoutcps
, 2, 3, 8, knots_circle
,
459 11, knots11
, 0.005, teapotmat
);
461 g_teapotSurfaces
.push_back(dynamic_cast<OSG::Surface
*>(spout
->getCore()));
463 teapotroot
->addChild(lid
);
464 teapotroot
->addChild(body
);
465 teapotroot
->addChild(handle
);
466 teapotroot
->addChild(spout
);
471 // This function creates a torus from a single NURBS surface
472 // using only 25 control points (of which 12 are unique).
473 // Similarly to the teapot, this uses the half-circle
474 // constructed from 3 control points (of which the middle point
475 // is infinite) which is then mirrored to form a full circle.
476 // (See the NURBS book [Piegl and Tiller], pp. 296, Ex7.1 (Figure 7.15)
477 // for details on the half-circle.)
478 OSG::NodeTransitPtr
makeTorus(void)
480 OSG::SimpleMaterialRefPtr torusmat
= OSG::SimpleMaterial::create();
482 torusmat
->setDiffuse( OSG::Color3f(1.0, 0.0, 0.2));
483 torusmat
->setAmbient( OSG::Color3f(0.2, 0.2, 0.2));
484 torusmat
->setEmission( OSG::Color3f(0.02, 0.02, 0.02) );
485 torusmat
->setSpecular( OSG::Color3f(0.78, 0.78, 0.78) );
486 torusmat
->setShininess( 128 );
488 float knots_circle
[8] = {0, 0, 0, 0.5, 0.5, 1, 1, 1};
489 float toruscps
[25][4] = {
490 { 1.00, 0, .75, 1}, //
492 { 1.00, 0, 1.25, 1}, //
500 {-1.00, 0, .75, 1}, //
502 {-1.00, 0, 1.25, 1}, //
505 { 0, -1.00, 0, 0}, //
517 OSG::NodeTransitPtr torus
= makeSurface(25, toruscps
, 2, 2, 8, knots_circle
,
518 8, knots_circle
, 0.005, torusmat
);
519 g_torusSurfaces
.push_back(dynamic_cast<OSG::Surface
*>(torus
->getCore()));
524 // This function creates a cylinder similarly to the teapot
525 // and the torus above. This time the cylinder is trimmed with
526 // a circle defined by 9 square-based control points to show
527 // an example of defining a circle without using infinite control
528 // points (see [Piegl and Tiller], pp. 299, Ex7.2 (Figure 7.16)) as
529 // well as to show how to define a rational trimming curve.
530 OSG::NodeTransitPtr
makeTrimmedCylinder(void)
532 OSG::SimpleMaterialRefPtr cylmat
= OSG::SimpleMaterial::create();
534 cylmat
->setDiffuse( OSG::Color3f(0.0, 0.8, 0.7));
535 cylmat
->setAmbient( OSG::Color3f(0.2, 0.2, 0.2));
536 cylmat
->setEmission( OSG::Color3f(0.02, 0.02, 0.02) );
537 cylmat
->setSpecular( OSG::Color3f(0.78, 0.78, 0.78) );
538 cylmat
->setShininess( 128 );
540 float knots4
[4] = {0, 0, 1, 1};
541 float knots_circle
[8] = {0, 0, 0, 0.5, 0.5, 1, 1, 1};
542 float knots_outertrim
[7] = {0, 0, 1, 2, 3, 4, 4};
543 float knots_trimcircle
[12] = {0, 0, 0, 0.25, 0.25, 0.5,
544 0.5, 0.75, 0.75, 1, 1, 1};
545 float cylcps
[10][4] = {
557 float outertrim_cps
[5][2] = {
564 float trimcircle_cps
[9][3] = {
566 {0.383016, 0.235702, 0.707107},
568 {0.324091, 0.235702, 0.707107},
570 {0.324091, 0.471405, 0.707107},
572 {0.383016, 0.471405, 0.707107},
575 OSG::NodeTransitPtr cylnode
= makeSurface(10, cylcps
, 2, 1, 8, knots_circle
,
576 4, knots4
, 0.001, cylmat
);
577 OSG::Surface
*s
= dynamic_cast<OSG::Surface
*>(cylnode
->getCore());
578 // add outer trimming around the domain
579 addTrimCurve(s
, 5, outertrim_cps
, 1, 7, knots_outertrim
, true);
580 // add inside circle trimming
581 addTrimCurve(s
, 9, trimcircle_cps
, 2, 12, knots_trimcircle
, true);
583 g_cylinderSurfaces
.push_back(
584 dynamic_cast<OSG::Surface
*>(cylnode
->getCore()));
589 OSG::NodeTransitPtr
makeScene(void)
591 OSG::NodeTransitPtr root
= OSG::makeCoredNode
<OSG::Switch
>();
593 root
->addChild(makeTeapot());
594 root
->addChild(makeTorus());
595 root
->addChild(makeTrimmedCylinder());
600 int main(int argc
, char **argv
)
602 printf("Press the keys '1', '2' and '3' in order to switch between "
603 "the different example objects.\n");
605 OSG::osgInit(argc
,argv
);
607 glutInit(&argc
, argv
);
608 glutInitWindowSize(800,600);
609 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
611 int winid
= glutCreateWindow("OpenSG");
613 glutReshapeFunc(reshape
);
614 glutDisplayFunc(display
);
615 glutIdleFunc(display
);
616 glutMouseFunc(mouse
);
617 glutMotionFunc(motion
);
618 glutKeyboardFunc(keyboard
);
621 OSG::GLUTWindowRefPtr gwin
= OSG::GLUTWindow::create();
622 gwin
->setGlutId(winid
);
626 g_scene
= makeScene();
629 if ( g_scene
== NULL
)
631 std::cerr
<<"makeScene returned NullFC, exiting..."<<std::endl
;
635 // create the SimpleSceneManager helper
636 g_mgr
= OSG::SimpleSceneManager::create();
638 // create the window and initial camera/viewport
639 g_mgr
->setWindow( gwin
);
640 // tell the manager what to manage
641 g_mgr
->setRoot ( g_scene
);
643 // show the whole scene
646 OSG::SolidBackgroundRefPtr bgr
= OSG::SolidBackground::create();
647 bgr
->setColor(OSG::Color3f( 0.7, 0.7, 0.7 ));
648 g_mgr
->getWindow()->getPort(0)->setBackground(bgr
);