diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8.1/examples/Demo/CDemo.cpp | 815 |
1 files changed, 815 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8.1/examples/Demo/CDemo.cpp b/libraries/irrlicht-1.8.1/examples/Demo/CDemo.cpp new file mode 100644 index 0000000..1ce72a9 --- /dev/null +++ b/libraries/irrlicht-1.8.1/examples/Demo/CDemo.cpp | |||
@@ -0,0 +1,815 @@ | |||
1 | // This is a Demo of the Irrlicht Engine (c) 2005-2009 by N.Gebhardt. | ||
2 | // This file is not documented. | ||
3 | |||
4 | #include "CDemo.h" | ||
5 | |||
6 | CDemo::CDemo(bool f, bool m, bool s, bool a, bool v, bool fsaa, video::E_DRIVER_TYPE d) | ||
7 | : fullscreen(f), music(m), shadows(s), additive(a), vsync(v), aa(fsaa), | ||
8 | driverType(d), device(0), | ||
9 | #ifdef USE_IRRKLANG | ||
10 | irrKlang(0), ballSound(0), impactSound(0), | ||
11 | #endif | ||
12 | #ifdef USE_SDL_MIXER | ||
13 | stream(0), ballSound(0), impactSound(0), | ||
14 | #endif | ||
15 | currentScene(-2), backColor(0), statusText(0), inOutFader(0), | ||
16 | quakeLevelMesh(0), quakeLevelNode(0), skyboxNode(0), model1(0), model2(0), | ||
17 | campFire(0), metaSelector(0), mapSelector(0), sceneStartTime(0), | ||
18 | timeForThisScene(0) | ||
19 | { | ||
20 | } | ||
21 | |||
22 | |||
23 | CDemo::~CDemo() | ||
24 | { | ||
25 | if (mapSelector) | ||
26 | mapSelector->drop(); | ||
27 | |||
28 | if (metaSelector) | ||
29 | metaSelector->drop(); | ||
30 | |||
31 | #ifdef USE_IRRKLANG | ||
32 | if (irrKlang) | ||
33 | irrKlang->drop(); | ||
34 | #endif | ||
35 | } | ||
36 | |||
37 | |||
38 | void CDemo::run() | ||
39 | { | ||
40 | core::dimension2d<u32> resolution ( 800, 600 ); | ||
41 | |||
42 | if ( driverType == video::EDT_BURNINGSVIDEO || driverType == video::EDT_SOFTWARE ) | ||
43 | { | ||
44 | resolution.Width = 640; | ||
45 | resolution.Height = 480; | ||
46 | } | ||
47 | |||
48 | irr::SIrrlichtCreationParameters params; | ||
49 | params.DriverType=driverType; | ||
50 | params.WindowSize=resolution; | ||
51 | params.Bits=32; | ||
52 | params.Fullscreen=fullscreen; | ||
53 | params.Stencilbuffer=shadows; | ||
54 | params.Vsync=vsync; | ||
55 | params.AntiAlias=aa; | ||
56 | params.EventReceiver=this; | ||
57 | |||
58 | device = createDeviceEx(params); | ||
59 | if (!device) | ||
60 | return; | ||
61 | |||
62 | if (device->getFileSystem()->existFile("irrlicht.dat")) | ||
63 | device->getFileSystem()->addFileArchive("irrlicht.dat"); | ||
64 | else | ||
65 | device->getFileSystem()->addFileArchive("../../media/irrlicht.dat"); | ||
66 | if (device->getFileSystem()->existFile("map-20kdm2.pk3")) | ||
67 | device->getFileSystem()->addFileArchive("map-20kdm2.pk3"); | ||
68 | else | ||
69 | device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3"); | ||
70 | |||
71 | video::IVideoDriver* driver = device->getVideoDriver(); | ||
72 | scene::ISceneManager* smgr = device->getSceneManager(); | ||
73 | gui::IGUIEnvironment* guienv = device->getGUIEnvironment(); | ||
74 | |||
75 | device->setWindowCaption(L"Irrlicht Engine Demo"); | ||
76 | |||
77 | // set ambient light | ||
78 | smgr->setAmbientLight ( video::SColorf ( 0x00c0c0c0 ) ); | ||
79 | |||
80 | wchar_t tmp[255]; | ||
81 | |||
82 | // draw everything | ||
83 | |||
84 | s32 now = 0; | ||
85 | s32 lastfps = 0; | ||
86 | sceneStartTime = device->getTimer()->getTime(); | ||
87 | while(device->run() && driver) | ||
88 | { | ||
89 | if (device->isWindowActive()) | ||
90 | { | ||
91 | #ifdef USE_IRRKLANG | ||
92 | // update 3D position for sound engine | ||
93 | scene::ICameraSceneNode* cam = smgr->getActiveCamera(); | ||
94 | if (cam && irrKlang) | ||
95 | irrKlang->setListenerPosition(cam->getAbsolutePosition(), cam->getTarget()); | ||
96 | #endif | ||
97 | |||
98 | // load next scene if necessary | ||
99 | now = device->getTimer()->getTime(); | ||
100 | if (now - sceneStartTime > timeForThisScene && timeForThisScene!=-1) | ||
101 | switchToNextScene(); | ||
102 | |||
103 | createParticleImpacts(); | ||
104 | |||
105 | driver->beginScene(timeForThisScene != -1, true, backColor); | ||
106 | |||
107 | smgr->drawAll(); | ||
108 | guienv->drawAll(); | ||
109 | driver->endScene(); | ||
110 | |||
111 | // write statistics | ||
112 | const s32 nowfps = driver->getFPS(); | ||
113 | |||
114 | swprintf(tmp, 255, L"%ls fps:%3d triangles:%0.3f mio/s", | ||
115 | driver->getName(), driver->getFPS(), | ||
116 | driver->getPrimitiveCountDrawn(1) * (1.f / 1000000.f)); | ||
117 | |||
118 | statusText->setText(tmp); | ||
119 | if ( nowfps != lastfps ) | ||
120 | { | ||
121 | device->setWindowCaption(tmp); | ||
122 | lastfps = nowfps; | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
127 | device->drop(); | ||
128 | } | ||
129 | |||
130 | |||
131 | bool CDemo::OnEvent(const SEvent& event) | ||
132 | { | ||
133 | if (!device) | ||
134 | return false; | ||
135 | |||
136 | if (event.EventType == EET_KEY_INPUT_EVENT && | ||
137 | event.KeyInput.Key == KEY_ESCAPE && | ||
138 | event.KeyInput.PressedDown == false) | ||
139 | { | ||
140 | // user wants to quit. | ||
141 | if (currentScene < 3) | ||
142 | timeForThisScene = 0; | ||
143 | else | ||
144 | device->closeDevice(); | ||
145 | } | ||
146 | else | ||
147 | if (((event.EventType == EET_KEY_INPUT_EVENT && | ||
148 | event.KeyInput.Key == KEY_SPACE && | ||
149 | event.KeyInput.PressedDown == false) || | ||
150 | (event.EventType == EET_MOUSE_INPUT_EVENT && | ||
151 | event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)) && | ||
152 | currentScene == 3) | ||
153 | { | ||
154 | // shoot | ||
155 | shoot(); | ||
156 | } | ||
157 | else | ||
158 | if (event.EventType == EET_KEY_INPUT_EVENT && | ||
159 | event.KeyInput.Key == KEY_F9 && | ||
160 | event.KeyInput.PressedDown == false) | ||
161 | { | ||
162 | video::IImage* image = device->getVideoDriver()->createScreenShot(); | ||
163 | if (image) | ||
164 | { | ||
165 | device->getVideoDriver()->writeImageToFile(image, "screenshot.bmp"); | ||
166 | device->getVideoDriver()->writeImageToFile(image, "screenshot.png"); | ||
167 | device->getVideoDriver()->writeImageToFile(image, "screenshot.tga"); | ||
168 | device->getVideoDriver()->writeImageToFile(image, "screenshot.ppm"); | ||
169 | device->getVideoDriver()->writeImageToFile(image, "screenshot.jpg"); | ||
170 | device->getVideoDriver()->writeImageToFile(image, "screenshot.pcx"); | ||
171 | image->drop(); | ||
172 | } | ||
173 | } | ||
174 | else | ||
175 | if (device->getSceneManager()->getActiveCamera()) | ||
176 | { | ||
177 | device->getSceneManager()->getActiveCamera()->OnEvent(event); | ||
178 | return true; | ||
179 | } | ||
180 | |||
181 | return false; | ||
182 | } | ||
183 | |||
184 | |||
185 | void CDemo::switchToNextScene() | ||
186 | { | ||
187 | currentScene++; | ||
188 | if (currentScene > 3) | ||
189 | currentScene = 1; | ||
190 | |||
191 | scene::ISceneManager* sm = device->getSceneManager(); | ||
192 | scene::ISceneNodeAnimator* sa = 0; | ||
193 | scene::ICameraSceneNode* camera = 0; | ||
194 | |||
195 | camera = sm->getActiveCamera(); | ||
196 | if (camera) | ||
197 | { | ||
198 | sm->setActiveCamera(0); | ||
199 | camera->remove(); | ||
200 | camera = 0; | ||
201 | } | ||
202 | |||
203 | switch(currentScene) | ||
204 | { | ||
205 | case -1: // loading screen | ||
206 | timeForThisScene = 0; | ||
207 | createLoadingScreen(); | ||
208 | break; | ||
209 | |||
210 | case 0: // load scene | ||
211 | timeForThisScene = 0; | ||
212 | loadSceneData(); | ||
213 | break; | ||
214 | |||
215 | case 1: // panorama camera | ||
216 | { | ||
217 | currentScene += 1; | ||
218 | //camera = sm->addCameraSceneNode(0, core::vector3df(0,0,0), core::vector3df(-586,708,52)); | ||
219 | //camera->setTarget(core::vector3df(0,400,0)); | ||
220 | |||
221 | core::array<core::vector3df> points; | ||
222 | |||
223 | points.push_back(core::vector3df(-931.473755f, 138.300003f, 987.279114f)); // -49873 | ||
224 | points.push_back(core::vector3df(-847.902222f, 136.757553f, 915.792725f)); // -50559 | ||
225 | points.push_back(core::vector3df(-748.680420f, 152.254501f, 826.418945f)); // -51964 | ||
226 | points.push_back(core::vector3df(-708.428406f, 213.569580f, 784.466675f)); // -53251 | ||
227 | points.push_back(core::vector3df(-686.217651f, 288.141174f, 762.965576f)); // -54015 | ||
228 | points.push_back(core::vector3df(-679.685059f, 365.095612f, 756.551453f)); // -54733 | ||
229 | points.push_back(core::vector3df(-671.317871f, 447.360107f, 749.394592f)); // -55588 | ||
230 | points.push_back(core::vector3df(-669.468445f, 583.335632f, 747.711853f)); // -56178 | ||
231 | points.push_back(core::vector3df(-667.611267f, 727.313232f, 746.018250f)); // -56757 | ||
232 | points.push_back(core::vector3df(-665.853210f, 862.791931f, 744.436096f)); // -57859 | ||
233 | points.push_back(core::vector3df(-642.649597f, 1026.047607f, 724.259827f)); // -59705 | ||
234 | points.push_back(core::vector3df(-517.793884f, 838.396790f, 490.326050f)); // -60983 | ||
235 | points.push_back(core::vector3df(-474.387299f, 715.691467f, 344.639984f)); // -61629 | ||
236 | points.push_back(core::vector3df(-444.600250f, 601.155701f, 180.938095f)); // -62319 | ||
237 | points.push_back(core::vector3df(-414.808899f, 479.691406f, 4.866660f)); // -63048 | ||
238 | points.push_back(core::vector3df(-410.418945f, 429.642242f, -134.332687f)); // -63757 | ||
239 | points.push_back(core::vector3df(-399.837585f, 411.498383f, -349.350983f)); // -64418 | ||
240 | points.push_back(core::vector3df(-390.756653f, 403.970093f, -524.454407f)); // -65005 | ||
241 | points.push_back(core::vector3df(-334.864227f, 350.065491f, -732.397400f)); // -65701 | ||
242 | points.push_back(core::vector3df(-195.253387f, 349.577209f, -812.475891f)); // -66335 | ||
243 | points.push_back(core::vector3df(16.255573f, 363.743134f, -833.800415f)); // -67170 | ||
244 | points.push_back(core::vector3df(234.940964f, 352.957825f, -820.150696f)); // -67939 | ||
245 | points.push_back(core::vector3df(436.797668f, 349.236450f, -816.914185f)); // -68596 | ||
246 | points.push_back(core::vector3df(575.236206f, 356.244812f, -719.788513f)); // -69166 | ||
247 | points.push_back(core::vector3df(594.131042f, 387.173828f, -609.675598f)); // -69744 | ||
248 | points.push_back(core::vector3df(617.615234f, 412.002899f, -326.174072f)); // -70640 | ||
249 | points.push_back(core::vector3df(606.456848f, 403.221954f, -104.179291f)); // -71390 | ||
250 | points.push_back(core::vector3df(610.958252f, 407.037750f, 117.209778f)); // -72085 | ||
251 | points.push_back(core::vector3df(597.956909f, 395.167877f, 345.942200f)); // -72817 | ||
252 | points.push_back(core::vector3df(587.383118f, 391.444519f, 566.098633f)); // -73477 | ||
253 | points.push_back(core::vector3df(559.572449f, 371.991333f, 777.689453f)); // -74124 | ||
254 | points.push_back(core::vector3df(423.753204f, 329.990051f, 925.859741f)); // -74941 | ||
255 | points.push_back(core::vector3df(247.520050f, 252.818954f, 935.311829f)); // -75651 | ||
256 | points.push_back(core::vector3df(114.756012f, 199.799759f, 805.014160f)); | ||
257 | points.push_back(core::vector3df(96.783348f, 181.639481f, 648.188110f)); | ||
258 | points.push_back(core::vector3df(97.865623f, 138.905975f, 484.812561f)); | ||
259 | points.push_back(core::vector3df(99.612457f, 102.463669f, 347.603210f)); | ||
260 | points.push_back(core::vector3df(99.612457f, 102.463669f, 347.603210f)); | ||
261 | points.push_back(core::vector3df(99.612457f, 102.463669f, 347.603210f)); | ||
262 | |||
263 | timeForThisScene = (points.size()-3)* 1000; | ||
264 | |||
265 | camera = sm->addCameraSceneNode(0, points[0], core::vector3df(0 ,400,0)); | ||
266 | //camera->setTarget(core::vector3df(0,400,0)); | ||
267 | |||
268 | sa = sm->createFollowSplineAnimator(device->getTimer()->getTime(), | ||
269 | points); | ||
270 | camera->addAnimator(sa); | ||
271 | sa->drop(); | ||
272 | |||
273 | model1->setVisible(false); | ||
274 | model2->setVisible(false); | ||
275 | campFire->setVisible(false); | ||
276 | inOutFader->fadeIn(7000); | ||
277 | } | ||
278 | break; | ||
279 | |||
280 | case 2: // down fly anim camera | ||
281 | camera = sm->addCameraSceneNode(0, core::vector3df(100,40,-80), core::vector3df(844,670,-885)); | ||
282 | sa = sm->createFlyStraightAnimator(core::vector3df(94, 1002, 127), | ||
283 | core::vector3df(108, 15, -60), 10000, true); | ||
284 | camera->addAnimator(sa); | ||
285 | timeForThisScene = 9900; | ||
286 | model1->setVisible(true); | ||
287 | model2->setVisible(false); | ||
288 | campFire->setVisible(false); | ||
289 | sa->drop(); | ||
290 | break; | ||
291 | |||
292 | case 3: // interactive, go around | ||
293 | { | ||
294 | model1->setVisible(true); | ||
295 | model2->setVisible(true); | ||
296 | campFire->setVisible(true); | ||
297 | timeForThisScene = -1; | ||
298 | |||
299 | SKeyMap keyMap[9]; | ||
300 | keyMap[0].Action = EKA_MOVE_FORWARD; | ||
301 | keyMap[0].KeyCode = KEY_UP; | ||
302 | keyMap[1].Action = EKA_MOVE_FORWARD; | ||
303 | keyMap[1].KeyCode = KEY_KEY_W; | ||
304 | |||
305 | keyMap[2].Action = EKA_MOVE_BACKWARD; | ||
306 | keyMap[2].KeyCode = KEY_DOWN; | ||
307 | keyMap[3].Action = EKA_MOVE_BACKWARD; | ||
308 | keyMap[3].KeyCode = KEY_KEY_S; | ||
309 | |||
310 | keyMap[4].Action = EKA_STRAFE_LEFT; | ||
311 | keyMap[4].KeyCode = KEY_LEFT; | ||
312 | keyMap[5].Action = EKA_STRAFE_LEFT; | ||
313 | keyMap[5].KeyCode = KEY_KEY_A; | ||
314 | |||
315 | keyMap[6].Action = EKA_STRAFE_RIGHT; | ||
316 | keyMap[6].KeyCode = KEY_RIGHT; | ||
317 | keyMap[7].Action = EKA_STRAFE_RIGHT; | ||
318 | keyMap[7].KeyCode = KEY_KEY_D; | ||
319 | |||
320 | keyMap[8].Action = EKA_JUMP_UP; | ||
321 | keyMap[8].KeyCode = KEY_KEY_J; | ||
322 | |||
323 | camera = sm->addCameraSceneNodeFPS(0, 100.0f, .4f, -1, keyMap, 9, false, 3.f); | ||
324 | camera->setPosition(core::vector3df(108,140,-140)); | ||
325 | camera->setFarValue(5000.0f); | ||
326 | |||
327 | scene::ISceneNodeAnimatorCollisionResponse* collider = | ||
328 | sm->createCollisionResponseAnimator( | ||
329 | metaSelector, camera, core::vector3df(25,50,25), | ||
330 | core::vector3df(0, quakeLevelMesh ? -10.f : 0.0f,0), | ||
331 | core::vector3df(0,45,0), 0.005f); | ||
332 | |||
333 | camera->addAnimator(collider); | ||
334 | collider->drop(); | ||
335 | } | ||
336 | break; | ||
337 | } | ||
338 | |||
339 | sceneStartTime = device->getTimer()->getTime(); | ||
340 | } | ||
341 | |||
342 | |||
343 | void CDemo::loadSceneData() | ||
344 | { | ||
345 | // load quake level | ||
346 | |||
347 | video::IVideoDriver* driver = device->getVideoDriver(); | ||
348 | scene::ISceneManager* sm = device->getSceneManager(); | ||
349 | |||
350 | // Quake3 Shader controls Z-Writing | ||
351 | sm->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); | ||
352 | |||
353 | quakeLevelMesh = (scene::IQ3LevelMesh*) sm->getMesh("maps/20kdm2.bsp"); | ||
354 | |||
355 | if (quakeLevelMesh) | ||
356 | { | ||
357 | u32 i; | ||
358 | |||
359 | //move all quake level meshes (non-realtime) | ||
360 | core::matrix4 m; | ||
361 | m.setTranslation(core::vector3df(-1300,-70,-1249)); | ||
362 | |||
363 | for ( i = 0; i != scene::quake3::E_Q3_MESH_SIZE; ++i ) | ||
364 | sm->getMeshManipulator()->transform(quakeLevelMesh->getMesh(i), m); | ||
365 | |||
366 | quakeLevelNode = sm->addOctreeSceneNode( | ||
367 | quakeLevelMesh->getMesh( scene::quake3::E_Q3_MESH_GEOMETRY)); | ||
368 | if (quakeLevelNode) | ||
369 | { | ||
370 | //quakeLevelNode->setPosition(core::vector3df(-1300,-70,-1249)); | ||
371 | quakeLevelNode->setVisible(true); | ||
372 | |||
373 | // create map triangle selector | ||
374 | mapSelector = sm->createOctreeTriangleSelector(quakeLevelMesh->getMesh(0), | ||
375 | quakeLevelNode, 128); | ||
376 | |||
377 | // if not using shader and no gamma it's better to use more lighting, because | ||
378 | // quake3 level are usually dark | ||
379 | quakeLevelNode->setMaterialType ( video::EMT_LIGHTMAP_M4 ); | ||
380 | |||
381 | // set additive blending if wanted | ||
382 | if (additive) | ||
383 | quakeLevelNode->setMaterialType(video::EMT_LIGHTMAP_ADD); | ||
384 | } | ||
385 | |||
386 | // the additional mesh can be quite huge and is unoptimized | ||
387 | scene::IMesh * additional_mesh = quakeLevelMesh->getMesh ( scene::quake3::E_Q3_MESH_ITEMS ); | ||
388 | |||
389 | for ( i = 0; i!= additional_mesh->getMeshBufferCount (); ++i ) | ||
390 | { | ||
391 | scene::IMeshBuffer *meshBuffer = additional_mesh->getMeshBuffer ( i ); | ||
392 | const video::SMaterial &material = meshBuffer->getMaterial(); | ||
393 | |||
394 | //! The ShaderIndex is stored in the material parameter | ||
395 | s32 shaderIndex = (s32) material.MaterialTypeParam2; | ||
396 | |||
397 | // the meshbuffer can be rendered without additional support, or it has no shader | ||
398 | const scene::quake3::IShader *shader = quakeLevelMesh->getShader ( shaderIndex ); | ||
399 | if ( 0 == shader ) | ||
400 | { | ||
401 | continue; | ||
402 | } | ||
403 | // Now add the MeshBuffer(s) with the current Shader to the Manager | ||
404 | sm->addQuake3SceneNode ( meshBuffer, shader ); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | // load sydney model and create 2 instances | ||
409 | |||
410 | scene::IAnimatedMesh* mesh = 0; | ||
411 | mesh = sm->getMesh("../../media/sydney.md2"); | ||
412 | if (mesh) | ||
413 | { | ||
414 | model1 = sm->addAnimatedMeshSceneNode(mesh); | ||
415 | if (model1) | ||
416 | { | ||
417 | model1->setMaterialTexture(0, driver->getTexture("../../media/spheremap.jpg")); | ||
418 | model1->setPosition(core::vector3df(100,40,-80)); | ||
419 | model1->setScale(core::vector3df(2,2,2)); | ||
420 | model1->setMD2Animation(scene::EMAT_STAND); | ||
421 | model1->setMaterialFlag(video::EMF_LIGHTING, false); | ||
422 | model1->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); | ||
423 | model1->setMaterialType(video::EMT_SPHERE_MAP); | ||
424 | model1->addShadowVolumeSceneNode(); | ||
425 | } | ||
426 | |||
427 | model2 = sm->addAnimatedMeshSceneNode(mesh); | ||
428 | if (model2) | ||
429 | { | ||
430 | model2->setPosition(core::vector3df(180,15,-60)); | ||
431 | model2->setScale(core::vector3df(2,2,2)); | ||
432 | model2->setMD2Animation(scene::EMAT_RUN); | ||
433 | model2->setMaterialTexture(0, device->getVideoDriver()->getTexture("../../media/sydney.bmp")); | ||
434 | model2->setMaterialFlag(video::EMF_LIGHTING, true); | ||
435 | model2->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); | ||
436 | model2->addShadowVolumeSceneNode(); | ||
437 | } | ||
438 | } | ||
439 | |||
440 | scene::ISceneNodeAnimator* anim = 0; | ||
441 | |||
442 | // create sky box | ||
443 | driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); | ||
444 | skyboxNode = sm->addSkyBoxSceneNode( | ||
445 | driver->getTexture("../../media/irrlicht2_up.jpg"), | ||
446 | driver->getTexture("../../media/irrlicht2_dn.jpg"), | ||
447 | driver->getTexture("../../media/irrlicht2_lf.jpg"), | ||
448 | driver->getTexture("../../media/irrlicht2_rt.jpg"), | ||
449 | driver->getTexture("../../media/irrlicht2_ft.jpg"), | ||
450 | driver->getTexture("../../media/irrlicht2_bk.jpg")); | ||
451 | driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true); | ||
452 | |||
453 | // create walk-between-portals animation | ||
454 | |||
455 | core::vector3df waypoint[2]; | ||
456 | waypoint[0].set(-150,40,100); | ||
457 | waypoint[1].set(350,40,100); | ||
458 | |||
459 | if (model2) | ||
460 | { | ||
461 | anim = device->getSceneManager()->createFlyStraightAnimator( | ||
462 | waypoint[0], waypoint[1], 2000, true); | ||
463 | model2->addAnimator(anim); | ||
464 | anim->drop(); | ||
465 | } | ||
466 | |||
467 | // create animation for portals; | ||
468 | |||
469 | core::array<video::ITexture*> textures; | ||
470 | for (s32 g=1; g<8; ++g) | ||
471 | { | ||
472 | core::stringc tmp("../../media/portal"); | ||
473 | tmp += g; | ||
474 | tmp += ".bmp"; | ||
475 | video::ITexture* t = driver->getTexture( tmp ); | ||
476 | textures.push_back(t); | ||
477 | } | ||
478 | |||
479 | anim = sm->createTextureAnimator(textures, 100); | ||
480 | |||
481 | // create portals | ||
482 | |||
483 | scene::IBillboardSceneNode* bill = 0; | ||
484 | |||
485 | for (int r=0; r<2; ++r) | ||
486 | { | ||
487 | bill = sm->addBillboardSceneNode(0, core::dimension2d<f32>(100,100), | ||
488 | waypoint[r]+ core::vector3df(0,20,0)); | ||
489 | bill->setMaterialFlag(video::EMF_LIGHTING, false); | ||
490 | bill->setMaterialTexture(0, driver->getTexture("../../media/portal1.bmp")); | ||
491 | bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); | ||
492 | bill->addAnimator(anim); | ||
493 | } | ||
494 | |||
495 | anim->drop(); | ||
496 | |||
497 | // create cirlce flying dynamic light with transparent billboard attached | ||
498 | |||
499 | scene::ILightSceneNode* light = 0; | ||
500 | |||
501 | light = sm->addLightSceneNode(0, | ||
502 | core::vector3df(0,0,0), video::SColorf(1.0f, 1.0f, 1.f, 1.0f), 500.f); | ||
503 | |||
504 | anim = sm->createFlyCircleAnimator( | ||
505 | core::vector3df(100,150,80), 80.0f, 0.0005f); | ||
506 | |||
507 | light->addAnimator(anim); | ||
508 | anim->drop(); | ||
509 | |||
510 | bill = device->getSceneManager()->addBillboardSceneNode( | ||
511 | light, core::dimension2d<f32>(40,40)); | ||
512 | bill->setMaterialFlag(video::EMF_LIGHTING, false); | ||
513 | bill->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp")); | ||
514 | bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); | ||
515 | |||
516 | // create meta triangle selector with all triangles selectors in it. | ||
517 | metaSelector = sm->createMetaTriangleSelector(); | ||
518 | metaSelector->addTriangleSelector(mapSelector); | ||
519 | |||
520 | // create camp fire | ||
521 | |||
522 | campFire = sm->addParticleSystemSceneNode(false); | ||
523 | campFire->setPosition(core::vector3df(100,120,600)); | ||
524 | campFire->setScale(core::vector3df(2,2,2)); | ||
525 | |||
526 | scene::IParticleEmitter* em = campFire->createBoxEmitter( | ||
527 | core::aabbox3d<f32>(-7,0,-7,7,1,7), | ||
528 | core::vector3df(0.0f,0.06f,0.0f), | ||
529 | 80,100, video::SColor(1,255,255,255),video::SColor(1,255,255,255), 800,2000); | ||
530 | |||
531 | em->setMinStartSize(core::dimension2d<f32>(20.0f, 10.0f)); | ||
532 | em->setMaxStartSize(core::dimension2d<f32>(20.0f, 10.0f)); | ||
533 | campFire->setEmitter(em); | ||
534 | em->drop(); | ||
535 | |||
536 | scene::IParticleAffector* paf = campFire->createFadeOutParticleAffector(); | ||
537 | campFire->addAffector(paf); | ||
538 | paf->drop(); | ||
539 | |||
540 | campFire->setMaterialFlag(video::EMF_LIGHTING, false); | ||
541 | campFire->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); | ||
542 | campFire->setMaterialTexture(0, driver->getTexture("../../media/fireball.bmp")); | ||
543 | campFire->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); | ||
544 | |||
545 | // load music | ||
546 | |||
547 | #ifdef USE_IRRKLANG | ||
548 | if (music) | ||
549 | startIrrKlang(); | ||
550 | #endif | ||
551 | #ifdef USE_SDL_MIXER | ||
552 | if (music) | ||
553 | startSound(); | ||
554 | #endif | ||
555 | } | ||
556 | |||
557 | |||
558 | void CDemo::createLoadingScreen() | ||
559 | { | ||
560 | core::dimension2d<u32> size = device->getVideoDriver()->getScreenSize(); | ||
561 | |||
562 | device->getCursorControl()->setVisible(false); | ||
563 | |||
564 | // setup loading screen | ||
565 | |||
566 | backColor.set(255,90,90,156); | ||
567 | |||
568 | // create in fader | ||
569 | |||
570 | inOutFader = device->getGUIEnvironment()->addInOutFader(); | ||
571 | inOutFader->setColor(backColor, video::SColor ( 0, 230, 230, 230 )); | ||
572 | |||
573 | // irrlicht logo | ||
574 | device->getGUIEnvironment()->addImage(device->getVideoDriver()->getTexture("../../media/irrlichtlogo2.png"), | ||
575 | core::position2d<s32>(5,5)); | ||
576 | |||
577 | // loading text | ||
578 | |||
579 | const int lwidth = size.Width - 20; | ||
580 | const int lheight = 16; | ||
581 | |||
582 | core::rect<int> pos(10, size.Height-lheight-10, 10+lwidth, size.Height-10); | ||
583 | |||
584 | device->getGUIEnvironment()->addImage(pos); | ||
585 | statusText = device->getGUIEnvironment()->addStaticText(L"Loading...", pos, true); | ||
586 | statusText->setOverrideColor(video::SColor(255,205,200,200)); | ||
587 | |||
588 | // load bigger font | ||
589 | |||
590 | device->getGUIEnvironment()->getSkin()->setFont( | ||
591 | device->getGUIEnvironment()->getFont("../../media/fonthaettenschweiler.bmp")); | ||
592 | |||
593 | // set new font color | ||
594 | |||
595 | device->getGUIEnvironment()->getSkin()->setColor(gui::EGDC_BUTTON_TEXT, | ||
596 | video::SColor(255,100,100,100)); | ||
597 | } | ||
598 | |||
599 | |||
600 | void CDemo::shoot() | ||
601 | { | ||
602 | scene::ISceneManager* sm = device->getSceneManager(); | ||
603 | scene::ICameraSceneNode* camera = sm->getActiveCamera(); | ||
604 | |||
605 | if (!camera || !mapSelector) | ||
606 | return; | ||
607 | |||
608 | SParticleImpact imp; | ||
609 | imp.when = 0; | ||
610 | |||
611 | // get line of camera | ||
612 | |||
613 | core::vector3df start = camera->getPosition(); | ||
614 | core::vector3df end = (camera->getTarget() - start); | ||
615 | end.normalize(); | ||
616 | start += end*8.0f; | ||
617 | end = start + (end * camera->getFarValue()); | ||
618 | |||
619 | core::triangle3df triangle; | ||
620 | |||
621 | core::line3d<f32> line(start, end); | ||
622 | |||
623 | // get intersection point with map | ||
624 | scene::ISceneNode* hitNode; | ||
625 | if (sm->getSceneCollisionManager()->getCollisionPoint( | ||
626 | line, mapSelector, end, triangle, hitNode)) | ||
627 | { | ||
628 | // collides with wall | ||
629 | core::vector3df out = triangle.getNormal(); | ||
630 | out.setLength(0.03f); | ||
631 | |||
632 | imp.when = 1; | ||
633 | imp.outVector = out; | ||
634 | imp.pos = end; | ||
635 | } | ||
636 | else | ||
637 | { | ||
638 | // doesnt collide with wall | ||
639 | core::vector3df start = camera->getPosition(); | ||
640 | core::vector3df end = (camera->getTarget() - start); | ||
641 | end.normalize(); | ||
642 | start += end*8.0f; | ||
643 | end = start + (end * camera->getFarValue()); | ||
644 | } | ||
645 | |||
646 | // create fire ball | ||
647 | scene::ISceneNode* node = 0; | ||
648 | node = sm->addBillboardSceneNode(0, | ||
649 | core::dimension2d<f32>(25,25), start); | ||
650 | |||
651 | node->setMaterialFlag(video::EMF_LIGHTING, false); | ||
652 | node->setMaterialTexture(0, device->getVideoDriver()->getTexture("../../media/fireball.bmp")); | ||
653 | node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); | ||
654 | |||
655 | f32 length = (f32)(end - start).getLength(); | ||
656 | const f32 speed = 0.6f; | ||
657 | u32 time = (u32)(length / speed); | ||
658 | |||
659 | scene::ISceneNodeAnimator* anim = 0; | ||
660 | |||
661 | // set flight line | ||
662 | |||
663 | anim = sm->createFlyStraightAnimator(start, end, time); | ||
664 | node->addAnimator(anim); | ||
665 | anim->drop(); | ||
666 | |||
667 | anim = sm->createDeleteAnimator(time); | ||
668 | node->addAnimator(anim); | ||
669 | anim->drop(); | ||
670 | |||
671 | if (imp.when) | ||
672 | { | ||
673 | // create impact note | ||
674 | imp.when = device->getTimer()->getTime() + (time - 100); | ||
675 | Impacts.push_back(imp); | ||
676 | } | ||
677 | |||
678 | // play sound | ||
679 | #ifdef USE_IRRKLANG | ||
680 | if (ballSound) | ||
681 | irrKlang->play2D(ballSound); | ||
682 | #endif | ||
683 | #ifdef USE_SDL_MIXER | ||
684 | if (ballSound) | ||
685 | playSound(ballSound); | ||
686 | #endif | ||
687 | } | ||
688 | |||
689 | |||
690 | void CDemo::createParticleImpacts() | ||
691 | { | ||
692 | u32 now = device->getTimer()->getTime(); | ||
693 | scene::ISceneManager* sm = device->getSceneManager(); | ||
694 | |||
695 | for (s32 i=0; i<(s32)Impacts.size(); ++i) | ||
696 | if (now > Impacts[i].when) | ||
697 | { | ||
698 | // create smoke particle system | ||
699 | scene::IParticleSystemSceneNode* pas = 0; | ||
700 | |||
701 | pas = sm->addParticleSystemSceneNode(false, 0, -1, Impacts[i].pos); | ||
702 | |||
703 | pas->setParticleSize(core::dimension2d<f32>(10.0f, 10.0f)); | ||
704 | |||
705 | scene::IParticleEmitter* em = pas->createBoxEmitter( | ||
706 | core::aabbox3d<f32>(-5,-5,-5,5,5,5), | ||
707 | Impacts[i].outVector, 20,40, video::SColor(50,255,255,255),video::SColor(50,255,255,255), | ||
708 | 1200,1600, 20); | ||
709 | |||
710 | pas->setEmitter(em); | ||
711 | em->drop(); | ||
712 | |||
713 | scene::IParticleAffector* paf = campFire->createFadeOutParticleAffector(); | ||
714 | pas->addAffector(paf); | ||
715 | paf->drop(); | ||
716 | |||
717 | pas->setMaterialFlag(video::EMF_LIGHTING, false); | ||
718 | pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); | ||
719 | pas->setMaterialTexture(0, device->getVideoDriver()->getTexture("../../media/smoke.bmp")); | ||
720 | pas->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); | ||
721 | |||
722 | scene::ISceneNodeAnimator* anim = sm->createDeleteAnimator(2000); | ||
723 | pas->addAnimator(anim); | ||
724 | anim->drop(); | ||
725 | |||
726 | // play impact sound | ||
727 | #ifdef USE_IRRKLANG | ||
728 | if (irrKlang) | ||
729 | { | ||
730 | irrklang::ISound* sound = | ||
731 | irrKlang->play3D(impactSound, Impacts[i].pos, false, false, true); | ||
732 | |||
733 | if (sound) | ||
734 | { | ||
735 | // adjust max value a bit to make to sound of an impact louder | ||
736 | sound->setMinDistance(400); | ||
737 | sound->drop(); | ||
738 | } | ||
739 | } | ||
740 | #endif | ||
741 | |||
742 | #ifdef USE_SDL_MIXER | ||
743 | if (impactSound) | ||
744 | playSound(impactSound); | ||
745 | #endif | ||
746 | |||
747 | // delete entry | ||
748 | Impacts.erase(i); | ||
749 | i--; | ||
750 | } | ||
751 | } | ||
752 | |||
753 | |||
754 | #ifdef USE_IRRKLANG | ||
755 | void CDemo::startIrrKlang() | ||
756 | { | ||
757 | irrKlang = irrklang::createIrrKlangDevice(); | ||
758 | |||
759 | if (!irrKlang) | ||
760 | return; | ||
761 | |||
762 | // play music | ||
763 | |||
764 | irrklang::ISound* snd = irrKlang->play2D("../../media/IrrlichtTheme.ogg", true, false, true); | ||
765 | if ( !snd ) | ||
766 | snd = irrKlang->play2D("IrrlichtTheme.ogg", true, false, true); | ||
767 | |||
768 | if (snd) | ||
769 | { | ||
770 | snd->setVolume(0.5f); // 50% volume | ||
771 | snd->drop(); | ||
772 | } | ||
773 | |||
774 | // preload both sound effects | ||
775 | |||
776 | ballSound = irrKlang->getSoundSource("../../media/ball.wav"); | ||
777 | impactSound = irrKlang->getSoundSource("../../media/impact.wav"); | ||
778 | } | ||
779 | #endif | ||
780 | |||
781 | |||
782 | #ifdef USE_SDL_MIXER | ||
783 | void CDemo::startSound() | ||
784 | { | ||
785 | stream = NULL; | ||
786 | ballSound = NULL; | ||
787 | impactSound = NULL; | ||
788 | |||
789 | SDL_Init(SDL_INIT_AUDIO); | ||
790 | |||
791 | if (Mix_OpenAudio(22050, AUDIO_S16, 2, 128)) | ||
792 | return; | ||
793 | |||
794 | stream = Mix_LoadMUS("../../media/IrrlichtTheme.ogg"); | ||
795 | if (stream) | ||
796 | Mix_PlayMusic(stream, -1); | ||
797 | |||
798 | ballSound = Mix_LoadWAV("../../media/ball.wav"); | ||
799 | impactSound = Mix_LoadWAV("../../media/impact.wav"); | ||
800 | } | ||
801 | |||
802 | void CDemo::playSound(Mix_Chunk *sample) | ||
803 | { | ||
804 | if (sample) | ||
805 | Mix_PlayChannel(-1, sample, 0); | ||
806 | } | ||
807 | |||
808 | void CDemo::pollSound(void) | ||
809 | { | ||
810 | SDL_Event event; | ||
811 | |||
812 | while (SDL_PollEvent(&event)) | ||
813 | ; | ||
814 | } | ||
815 | #endif | ||