~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to examples/Demo/CDemo.cpp

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
326
                        scene::ISceneNodeAnimatorCollisionResponse* collider =
 
327
                                sm->createCollisionResponseAnimator(
 
328
                                metaSelector, camera, core::vector3df(25,50,25),
 
329
                                core::vector3df(0, quakeLevelMesh ? -10.f : 0.0f,0),
 
330
                                        core::vector3df(0,45,0), 0.005f);
 
331
 
 
332
                        camera->addAnimator(collider);
 
333
                        collider->drop();
 
334
                }
 
335
                break;
 
336
        }
 
337
 
 
338
        sceneStartTime = device->getTimer()->getTime();
 
339
}
 
340
 
 
341
 
 
342
void CDemo::loadSceneData()
 
343
{
 
344
        // load quake level
 
345
 
 
346
        video::IVideoDriver* driver = device->getVideoDriver();
 
347
        scene::ISceneManager* sm = device->getSceneManager();
 
348
 
 
349
        // Quake3 Shader controls Z-Writing
 
350
        sm->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
 
351
 
 
352
        quakeLevelMesh = (scene::IQ3LevelMesh*) sm->getMesh("maps/20kdm2.bsp");
 
353
 
 
354
        if (quakeLevelMesh)
 
355
        {
 
356
                u32 i;
 
357
 
 
358
                //move all quake level meshes (non-realtime)
 
359
                core::matrix4 m;
 
360
                m.setTranslation(core::vector3df(-1300,-70,-1249));
 
361
 
 
362
                for ( i = 0; i != scene::quake3::E_Q3_MESH_SIZE; ++i )
 
363
                        sm->getMeshManipulator()->transform(quakeLevelMesh->getMesh(i), m);
 
364
 
 
365
                quakeLevelNode = sm->addOctreeSceneNode(
 
366
                                quakeLevelMesh->getMesh( scene::quake3::E_Q3_MESH_GEOMETRY));
 
367
                if (quakeLevelNode)
 
368
                {
 
369
                        //quakeLevelNode->setPosition(core::vector3df(-1300,-70,-1249));
 
370
                        quakeLevelNode->setVisible(true);
 
371
 
 
372
                        // create map triangle selector
 
373
                        mapSelector = sm->createOctreeTriangleSelector(quakeLevelMesh->getMesh(0),
 
374
                                quakeLevelNode, 128);
 
375
 
 
376
                        // if not using shader and no gamma it's better to use more lighting, because
 
377
                        // quake3 level are usually dark
 
378
                        quakeLevelNode->setMaterialType ( video::EMT_LIGHTMAP_M4 );
 
379
 
 
380
                        // set additive blending if wanted
 
381
                        if (additive)
 
382
                                quakeLevelNode->setMaterialType(video::EMT_LIGHTMAP_ADD);
 
383
                }
 
384
 
 
385
                // the additional mesh can be quite huge and is unoptimized
 
386
                scene::IMesh * additional_mesh = quakeLevelMesh->getMesh ( scene::quake3::E_Q3_MESH_ITEMS );
 
387
 
 
388
                for ( i = 0; i!= additional_mesh->getMeshBufferCount (); ++i )
 
389
                {
 
390
                        scene::IMeshBuffer *meshBuffer = additional_mesh->getMeshBuffer ( i );
 
391
                        const video::SMaterial &material = meshBuffer->getMaterial();
 
392
 
 
393
                        //! The ShaderIndex is stored in the material parameter
 
394
                        s32 shaderIndex = (s32) material.MaterialTypeParam2;
 
395
 
 
396
                        // the meshbuffer can be rendered without additional support, or it has no shader
 
397
                        const scene::quake3::IShader *shader = quakeLevelMesh->getShader ( shaderIndex );
 
398
                        if ( 0 == shader )
 
399
                        {
 
400
                                continue;
 
401
                        }
 
402
                        // Now add the MeshBuffer(s) with the current Shader to the Manager
 
403
                        sm->addQuake3SceneNode ( meshBuffer, shader );
 
404
                }
 
405
        }
 
406
 
 
407
        // load sydney model and create 2 instances
 
408
 
 
409
        scene::IAnimatedMesh* mesh = 0;
 
410
        mesh = sm->getMesh("../../media/sydney.md2");
 
411
        if (mesh)
 
412
        {
 
413
                model1 = sm->addAnimatedMeshSceneNode(mesh);
 
414
                if (model1)
 
415
                {
 
416
                        model1->setMaterialTexture(0, driver->getTexture("../../media/spheremap.jpg"));
 
417
                        model1->setPosition(core::vector3df(100,40,-80));
 
418
                        model1->setScale(core::vector3df(2,2,2));
 
419
                        model1->setMD2Animation(scene::EMAT_STAND);
 
420
                        model1->setMaterialFlag(video::EMF_LIGHTING, false);
 
421
                        model1->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
 
422
                        model1->setMaterialType(video::EMT_SPHERE_MAP);
 
423
                        model1->addShadowVolumeSceneNode();
 
424
                }
 
425
 
 
426
                model2 = sm->addAnimatedMeshSceneNode(mesh);
 
427
                if (model2)
 
428
                {
 
429
                        model2->setPosition(core::vector3df(180,15,-60));
 
430
                        model2->setScale(core::vector3df(2,2,2));
 
431
                        model2->setMD2Animation(scene::EMAT_RUN);
 
432
                        model2->setMaterialTexture(0, device->getVideoDriver()->getTexture("../../media/sydney.bmp"));
 
433
                        model2->setMaterialFlag(video::EMF_LIGHTING, true);
 
434
                        model1->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
 
435
                        model2->addShadowVolumeSceneNode();
 
436
                }
 
437
        }
 
438
 
 
439
        scene::ISceneNodeAnimator* anim = 0;
 
440
 
 
441
        // create sky box
 
442
        driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
 
443
        skyboxNode = sm->addSkyBoxSceneNode(
 
444
                driver->getTexture("../../media/irrlicht2_up.jpg"),
 
445
                driver->getTexture("../../media/irrlicht2_dn.jpg"),
 
446
                driver->getTexture("../../media/irrlicht2_lf.jpg"),
 
447
                driver->getTexture("../../media/irrlicht2_rt.jpg"),
 
448
                driver->getTexture("../../media/irrlicht2_ft.jpg"),
 
449
                driver->getTexture("../../media/irrlicht2_bk.jpg"));
 
450
        driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
 
451
 
 
452
        // create walk-between-portals animation
 
453
 
 
454
        core::vector3df waypoint[2];
 
455
        waypoint[0].set(-150,40,100);
 
456
        waypoint[1].set(350,40,100);
 
457
 
 
458
        if (model2)
 
459
        {
 
460
                anim = device->getSceneManager()->createFlyStraightAnimator(
 
461
                        waypoint[0], waypoint[1], 2000, true);
 
462
                model2->addAnimator(anim);
 
463
                anim->drop();
 
464
        }
 
465
 
 
466
        // create animation for portals;
 
467
 
 
468
        core::array<video::ITexture*> textures;
 
469
        for (s32 g=1; g<8; ++g)
 
470
        {
 
471
                core::stringc tmp("../../media/portal");
 
472
                tmp += g;
 
473
                tmp += ".bmp";
 
474
                video::ITexture* t = driver->getTexture( tmp );
 
475
                textures.push_back(t);
 
476
        }
 
477
 
 
478
        anim = sm->createTextureAnimator(textures, 100);
 
479
 
 
480
        // create portals
 
481
 
 
482
        scene::IBillboardSceneNode* bill = 0;
 
483
 
 
484
        for (int r=0; r<2; ++r)
 
485
        {
 
486
                bill = sm->addBillboardSceneNode(0, core::dimension2d<f32>(100,100),
 
487
                        waypoint[r]+ core::vector3df(0,20,0));
 
488
                bill->setMaterialFlag(video::EMF_LIGHTING, false);
 
489
                bill->setMaterialTexture(0, driver->getTexture("../../media/portal1.bmp"));
 
490
                bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
 
491
                bill->addAnimator(anim);
 
492
        }
 
493
 
 
494
        anim->drop();
 
495
 
 
496
        // create cirlce flying dynamic light with transparent billboard attached
 
497
 
 
498
        scene::ILightSceneNode* light = 0;
 
499
 
 
500
        light = sm->addLightSceneNode(0,
 
501
                core::vector3df(0,0,0), video::SColorf(1.0f, 1.0f, 1.f, 1.0f), 500.f);
 
502
 
 
503
        anim = sm->createFlyCircleAnimator(
 
504
                core::vector3df(100,150,80), 80.0f, 0.0005f);
 
505
 
 
506
        light->addAnimator(anim);
 
507
        anim->drop();
 
508
 
 
509
        bill = device->getSceneManager()->addBillboardSceneNode(
 
510
                light, core::dimension2d<f32>(40,40));
 
511
        bill->setMaterialFlag(video::EMF_LIGHTING, false);
 
512
        bill->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp"));
 
513
        bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
 
514
 
 
515
        // create meta triangle selector with all triangles selectors in it.
 
516
        metaSelector = sm->createMetaTriangleSelector();
 
517
        metaSelector->addTriangleSelector(mapSelector);
 
518
 
 
519
        // create camp fire
 
520
 
 
521
        campFire = sm->addParticleSystemSceneNode(false);
 
522
        campFire->setPosition(core::vector3df(100,120,600));
 
523
        campFire->setScale(core::vector3df(2,2,2));
 
524
 
 
525
        scene::IParticleEmitter* em = campFire->createBoxEmitter(
 
526
                core::aabbox3d<f32>(-7,0,-7,7,1,7),
 
527
                core::vector3df(0.0f,0.06f,0.0f),
 
528
                80,100, video::SColor(1,255,255,255),video::SColor(1,255,255,255), 800,2000);
 
529
 
 
530
        em->setMinStartSize(core::dimension2d<f32>(20.0f, 10.0f));
 
531
        em->setMaxStartSize(core::dimension2d<f32>(20.0f, 10.0f));
 
532
        campFire->setEmitter(em);
 
533
        em->drop();
 
534
 
 
535
        scene::IParticleAffector* paf = campFire->createFadeOutParticleAffector();
 
536
        campFire->addAffector(paf);
 
537
        paf->drop();
 
538
 
 
539
        campFire->setMaterialFlag(video::EMF_LIGHTING, false);
 
540
        campFire->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
 
541
        campFire->setMaterialTexture(0, driver->getTexture("../../media/fireball.bmp"));
 
542
        campFire->setMaterialType(video::EMT_ONETEXTURE_BLEND);
 
543
        campFire->getMaterial(0).MaterialTypeParam=video::pack_texureBlendFunc(video::EBF_ONE, video::EBF_ONE_MINUS_SRC_ALPHA, video::EMFN_MODULATE_1X, video::EAS_VERTEX_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(0,255,255,255),video::SColor(0,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_VERTEX_ALPHA);
 
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