fixed: compile issue
[opensg.git] / Examples / Simple / shadows.cpp
blob0fe0bfe54fa17cea3efd6626322d83391e3b83ee
1 // OpenSG Tutorial Example: Shadows
2 //
3 // This example shows realtime shadows via shadow maps.
5 #ifdef OSG_BUILD_ACTIVE
6 #include <OSGConfig.h>
8 #include <OSGGLUT.h>
9 #include <OSGSimpleGeometry.h>
10 #include <OSGGLUTWindow.h>
11 #include <OSGBaseFunctions.h>
13 #include <OSGSpotLight.h>
14 #include <OSGDirectionalLight.h>
15 #include <OSGPointLight.h>
16 #include <OSGPerspectiveCamera.h>
17 #include <OSGGradientBackground.h>
18 #include <OSGSolidBackground.h>
19 #include <OSGRenderAction.h>
20 #include <OSGImage.h>
21 #include <OSGSimpleMaterial.h>
22 #include <OSGTextureObjChunk.h>
23 #include <OSGTextureEnvChunk.h>
24 #include <OSGTransform.h>
25 #include <OSGGroup.h>
26 #include <OSGSimpleSceneManager.h>
27 #include <OSGSceneFileHandler.h>
29 // New Headers
30 #include <OSGSimpleShadowMapEngine.h>
31 #else
32 #include <OpenSG/OSGConfig.h>
34 #include <OpenSG/OSGGLUT.h>
35 #include <OpenSG/OSGSimpleGeometry.h>
36 #include <OpenSG/OSGGLUTWindow.h>
37 #include <OpenSG/OSGBaseFunctions.h>
39 #include <OpenSG/OSGSpotLight.h>
40 #include <OpenSG/OSGDirectionalLight.h>
41 #include <OpenSG/OSGPointLight.h>
42 #include <OpenSG/OSGPerspectiveCamera.h>
43 #include <OpenSG/OSGGradientBackground.h>
44 #include <OpenSG/OSGSolidBackground.h>
45 #include <OpenSG/OSGRenderAction.h>
46 #include <OpenSG/OSGImage.h>
47 #include <OpenSG/OSGSimpleMaterial.h>
48 #include <OpenSG/OSGTextureObjChunk.h>
49 #include <OpenSG/OSGTextureEnvChunk.h>
50 #include <OpenSG/OSGTransform.h>
51 #include <OpenSG/OSGGroup.h>
52 #include <OpenSG/OSGSimpleSceneManager.h>
53 #include <OpenSG/OSGSceneFileHandler.h>
55 // New Headers
56 #include <OpenSG/OSGSimpleShadowMapEngine.h>
57 #endif
61 This tutorial has quite a few global objects, to simplify the cleanup at
62 program exit we put them all in a struct.
65 struct GlobalObjects
67 OSG::SimpleSceneManagerRefPtr mgr;
69 OSG::GLUTWindowRefPtr gwin;
71 OSG::NodeRefPtr rootNode;
72 OSG::SpotLightRefPtr spot1_core;
73 OSG::SpotLightRefPtr spot2_core;
74 OSG::DirectionalLightRefPtr dir_core;
75 OSG::PointLightRefPtr point1_core;
76 OSG::PointLightRefPtr point2_core;
77 OSG::TransformRefPtr box_trans;
78 OSG::TransformRefPtr cylinder1_trans;
79 OSG::TransformRefPtr cylinder2_trans;
81 GlobalObjects(void) :
82 mgr (NULL),
84 gwin (NULL),
86 rootNode (NULL),
87 spot1_core (NULL),
88 spot2_core (NULL),
89 dir_core (NULL),
90 point1_core (NULL),
91 point2_core (NULL),
92 box_trans (NULL),
93 cylinder1_trans(NULL),
94 cylinder2_trans(NULL)
99 GlobalObjects *globals = NULL;
101 const OSG::UInt32 SM_RESOLUTION = 1024;
103 // forward declaration so we can have the interesting stuff upfront
104 int setupGLUT( int *argc, char *argv[] );
106 // Initialize GLUT & OpenSG and set up the scene
107 int main(int argc, char **argv)
109 printf("Press key '1' or '2' to switch between one and two light sources.\n");
110 // OSG init
111 OSG::osgInit(argc,argv);
113 globals = new GlobalObjects;
115 // open a new scope, because the pointers below should go out of scope
116 // before entering glutMainLoop.
117 // Otherwise OpenSG will complain about objects being alive after shutdown.
119 // GLUT init
120 int winid = setupGLUT(&argc, argv);
121 globals->gwin = OSG::GLUTWindow::create();
124 Construct a scene with a ground plane, some objects and two lights.
125 Nothing very interesting at this point.
126 See further down for the part relevant to shadows.
129 globals->rootNode = OSG::makeCoredNode<OSG::Group>();
130 OSG::NodeRefPtr scene = OSG::makeCoredNode<OSG::Group>();
132 // create lights
133 OSG::TransformRefPtr point1_trans;
134 OSG::NodeRefPtr point1 = OSG::makeCoredNode<OSG::PointLight>(&globals->point1_core);
135 OSG::NodeRefPtr point1_beacon = OSG::makeCoredNode<OSG::Transform >(&point1_trans);
137 point1_trans->editMatrix().setTranslate(0.0, 0.0, 15.0);
139 globals->point1_core->setAmbient(0.15f,0.15f,0.15f,1);
140 globals->point1_core->setDiffuse(0.4f,0.4f,0.4f,1);
141 globals->point1_core->setSpecular(0.0f,0.0f,0.0f,1);
142 globals->point1_core->setBeacon(point1_beacon);
143 globals->point1_core->setOn(true);
145 OSG::TransformRefPtr point2_trans;
146 OSG::NodeRefPtr point2 = OSG::makeCoredNode<OSG::PointLight>(&globals->point2_core);
147 OSG::NodeRefPtr point2_beacon = OSG::makeCoredNode<OSG::Transform >(&point2_trans);
149 point2_trans->editMatrix().setTranslate(2.5, 2.5, 15.0);
151 globals->point2_core->setAmbient(0.15f,0.15f,0.15f,1);
152 globals->point2_core->setDiffuse(0.4f,0.4f,0.4f,1);
153 globals->point2_core->setSpecular(0.0f,0.0f,0.0f,1);
154 globals->point2_core->setBeacon(point2_beacon);
155 globals->point2_core->setOn(true);
157 point1->addChild(point2);
158 point2->addChild(scene );
160 // create scene
162 // bottom
163 OSG::NodeRefPtr plane = OSG::makePlane(25.0, 25.0, 128, 128);
165 OSG::UChar8 imgdata[] =
166 { 255,0,0, 0,255,0, 0,0,255, 255,255,0 };
167 OSG::ImageRefPtr plane_img = OSG::Image::create();
168 plane_img->set(OSG::Image::OSG_RGB_PF, 2, 2, 1, 1, 1, 0, imgdata);
170 OSG::TextureObjChunkRefPtr plane_tex = OSG::TextureObjChunk::create();
171 plane_tex->setImage(plane_img);
172 plane_tex->setMinFilter(GL_LINEAR);
173 plane_tex->setMagFilter(GL_LINEAR);
174 plane_tex->setWrapS(GL_REPEAT);
175 plane_tex->setWrapT(GL_REPEAT);
177 OSG::TextureEnvChunkRefPtr plane_tex_env = OSG::TextureEnvChunk::create();
178 plane_tex_env->setEnvMode(GL_MODULATE);
180 OSG::SimpleMaterialRefPtr plane_mat = OSG::SimpleMaterial::create();
181 plane_mat->setAmbient(OSG::Color3f(0.3f,0.3f,0.3f));
182 plane_mat->setDiffuse(OSG::Color3f(1.0f,1.0f,1.0f));
183 plane_mat->addChunk(plane_tex);
184 plane_mat->addChunk(plane_tex_env);
186 OSG::GeometryRefPtr plane_geo = dynamic_cast<OSG::Geometry *>(plane->getCore());
187 plane_geo->setMaterial(plane_mat);
189 // box
190 OSG::NodeRefPtr box_trans_node = OSG::makeCoredNode<OSG::Transform>(&globals->box_trans);
191 globals->box_trans->editMatrix().setTranslate(0.0, 0.0, 2.0);
193 OSG::NodeRefPtr box = OSG::makeBox(8.0f, 8.0f, 0.8f, 10, 10 , 10);
194 box_trans_node->addChild(box);
196 OSG::SimpleMaterialRefPtr box_mat = OSG::SimpleMaterial::create();
197 box_mat->setAmbient(OSG::Color3f(0.0f,0.0f,0.0f));
198 box_mat->setDiffuse(OSG::Color3f(0.0f,0.0f,1.0f));
200 OSG::GeometryRefPtr box_geo = dynamic_cast<OSG::Geometry *>(box->getCore());
201 box_geo->setMaterial(box_mat);
203 // cylinder1
204 OSG::NodeRefPtr cylinder1_trans_node = OSG::makeCoredNode<OSG::Transform>(&globals->cylinder1_trans);
205 globals->cylinder1_trans->editMatrix().setTranslate(0.0, 0.0, 5.0);
207 OSG::NodeRefPtr cylinder1 = OSG::makeCylinder(10.0f, 0.4f, 32, true, true ,true);
208 cylinder1_trans_node->addChild(cylinder1);
210 OSG::SimpleMaterialRefPtr cylinder1_mat = OSG::SimpleMaterial::create();
211 cylinder1_mat->setAmbient(OSG::Color3f(0.0,0.0,0.0));
212 cylinder1_mat->setDiffuse(OSG::Color3f(1.0,0.0,0.0));
214 OSG::GeometryRefPtr cylinder1_geo = dynamic_cast<OSG::Geometry *>(cylinder1->getCore());
215 cylinder1_geo->setMaterial(cylinder1_mat);
217 // cylinder2
218 OSG::NodeRefPtr cylinder2_trans_node = OSG::makeCoredNode<OSG::Transform>(&globals->cylinder2_trans);
219 globals->cylinder2_trans->editMatrix().setTranslate(0.0, 0.0, 8.0);
221 OSG::NodeRefPtr cylinder2 = OSG::makeCylinder(10.0f, 0.4f, 32, true, true ,true);
222 cylinder2_trans_node->addChild(cylinder2);
224 OSG::SimpleMaterialRefPtr cylinder2_mat = OSG::SimpleMaterial::create();
225 cylinder2_mat->setAmbient(OSG::Color3f(0.0,0.0,0.0));
226 cylinder2_mat->setDiffuse(OSG::Color3f(0.0,1.0,0.0));
228 OSG::GeometryRefPtr cylinder2_geo = dynamic_cast<OSG::Geometry *>(cylinder2->getCore());
229 cylinder2_geo->setMaterial(cylinder2_mat);
231 // scene
232 scene->addChild(plane);
233 scene->addChild(box_trans_node);
234 scene->addChild(cylinder1_trans_node);
235 scene->addChild(cylinder2_trans_node);
237 globals->rootNode->addChild(point1);
238 globals->rootNode->addChild(point1_beacon);
239 globals->rootNode->addChild(point2_beacon);
241 globals->gwin->setGlutId(winid);
242 globals->gwin->init();
245 SHADOWS
246 Shadows are implemented as LightEngines (every Light can have one
247 to augment it's regular effect).
250 // create the engines
251 OSG::SimpleShadowMapEngineRefPtr ssme1 = OSG::SimpleShadowMapEngine::create();
252 OSG::SimpleShadowMapEngineRefPtr ssme2 = OSG::SimpleShadowMapEngine::create();
254 // add them to the light sources
255 globals->point1_core->setLightEngine(ssme1);
256 globals->point2_core->setLightEngine(ssme2);
258 ssme1->setWidth (SM_RESOLUTION);
259 ssme1->setHeight(SM_RESOLUTION);
260 ssme1->setShadowColor(OSG::Color4f(0.1f, 0.1f, 0.1f, 1.0f));
262 ssme2->setWidth (SM_RESOLUTION);
263 ssme2->setHeight(SM_RESOLUTION);
265 OSG::Vec3f min,max;
266 globals->rootNode->updateVolume();
267 globals->rootNode->getVolume ().getBounds( min, max );
269 OSG::commitChanges();
271 // create the SimpleSceneManager helper
272 globals->mgr = OSG::SimpleSceneManager::create();
274 globals->mgr->setWindow(globals->gwin );
275 globals->mgr->setRoot (globals->rootNode);
277 globals->mgr->turnHeadlightOff();
279 globals->mgr->showAll();
282 // GLUT main loop
283 glutMainLoop();
285 return 0;
289 // GLUT callback functions
292 //do Animation-Calculations here
293 void Animate()
295 static OSG::Real64 t0 = OSG::getSystemTime();
297 OSG::Real64 t = OSG::getSystemTime() - t0;
299 OSG::Real32 rotb = t * 10.0;
300 if(rotb > 360.0)
301 rotb -= 360.0;
303 OSG::Real32 rotc1 = t * 20.0;
304 if(rotc1 > 360.0)
305 rotc1 -= 360.0;
307 OSG::Real32 rotc2 = t * 40.0;
308 if(rotc2 > 360.0)
309 rotc2 -= 360.0;
311 OSG::Quaternion q;
312 q.setValueAsAxisDeg(0,0,1, rotb);
313 globals->box_trans->editMatrix().setRotate(q);
315 q.setValueAsAxisDeg(0,0,1, rotc1);
316 globals->cylinder1_trans->editMatrix().setRotate(q);
318 q.setValueAsAxisDeg(0,0,1, rotc2);
319 globals->cylinder2_trans->editMatrix().setRotate(q);
321 globals->mgr->redraw();
324 // redraw the window
325 void display(void)
327 globals->mgr->redraw();
330 // react to size changes
331 void reshape(int w, int h)
333 globals->mgr->resize( w, h );
334 glutPostRedisplay();
337 // react to mouse button presses
338 void mouse(int button, int state, int x, int y)
340 if ( state )
341 globals->mgr->mouseButtonRelease( button, x, y );
342 else
343 globals->mgr->mouseButtonPress( button, x, y );
344 glutPostRedisplay();
347 // react to mouse motions with pressed buttons
348 void motion(int x, int y)
350 globals->mgr->mouseMove( x, y );
351 glutPostRedisplay();
354 // react to keys
355 void keyboard(unsigned char k, int x, int y)
357 switch(k)
359 case 27:
361 // clean up global variables
362 globals->mgr = NULL;
364 delete globals;
366 OSG::osgExit();
367 exit(0);
369 break;
371 case '1':
373 globals->point1_core->setOn(true);
374 globals->point1_core->setAmbient(0.3f,0.3f,0.3f,1);
375 globals->point1_core->setDiffuse(0.8f,0.8f,0.8f,1);
377 globals->point2_core->setOn(false);
378 break;
381 case '2':
383 globals->point1_core->setAmbient(0.15f,0.15f,0.15f,1);
384 globals->point1_core->setDiffuse(0.4f,0.4f,0.4f,1);
385 globals->point1_core->setOn(true);
387 globals->point2_core->setAmbient(0.15f,0.15f,0.15f,1);
388 globals->point2_core->setDiffuse(0.4f,0.4f,0.4f,1);
389 globals->point2_core->setOn(true);
390 break;
393 case 'x':
395 OSG::SceneFileHandler::the()->write(globals->rootNode, "shadow.osb.gz", true);
398 glutPostRedisplay();
401 // setup the GLUT library which handles the windows for us
402 int setupGLUT(int *argc, char *argv[])
404 glutInit(argc, argv);
405 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
407 //Set WindowSize here
408 glutInitWindowSize(640,640);
409 int winid = glutCreateWindow("Shadow-Scene");
411 glutReshapeFunc(reshape);
412 glutDisplayFunc(display);
413 glutMouseFunc(mouse);
414 glutMotionFunc(motion);
415 glutKeyboardFunc(keyboard);
416 glutIdleFunc(Animate);
418 return winid;