aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/examples/08.SpecialFX/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/examples/08.SpecialFX/main.cpp616
1 files changed, 308 insertions, 308 deletions
diff --git a/libraries/irrlicht-1.8/examples/08.SpecialFX/main.cpp b/libraries/irrlicht-1.8/examples/08.SpecialFX/main.cpp
index d8f32f7..cf06da4 100644
--- a/libraries/irrlicht-1.8/examples/08.SpecialFX/main.cpp
+++ b/libraries/irrlicht-1.8/examples/08.SpecialFX/main.cpp
@@ -1,308 +1,308 @@
1/** Example 008 SpecialFX 1/** Example 008 SpecialFX
2 2
3This tutorials describes how to do special effects. It shows how to use stencil 3This tutorials describes how to do special effects. It shows how to use stencil
4buffer shadows, the particle system, billboards, dynamic light, and the water 4buffer shadows, the particle system, billboards, dynamic light, and the water
5surface scene node. 5surface scene node.
6 6
7We start like in some tutorials before. Please note that this time, the 7We start like in some tutorials before. Please note that this time, the
8'shadows' flag in createDevice() is set to true, for we want to have a dynamic 8'shadows' flag in createDevice() is set to true, for we want to have a dynamic
9shadow casted from an animated character. If this example runs too slow, 9shadow casted from an animated character. If this example runs too slow,
10set it to false. The Irrlicht Engine checks if your hardware doesn't support 10set it to false. The Irrlicht Engine checks if your hardware doesn't support
11the stencil buffer, and disables shadows by itself, but just in case the demo 11the stencil buffer, and disables shadows by itself, but just in case the demo
12runs slow on your hardware. 12runs slow on your hardware.
13*/ 13*/
14 14
15#include <irrlicht.h> 15#include <irrlicht.h>
16#include <iostream> 16#include <iostream>
17#include "driverChoice.h" 17#include "driverChoice.h"
18 18
19using namespace irr; 19using namespace irr;
20 20
21#ifdef _MSC_VER 21#ifdef _MSC_VER
22#pragma comment(lib, "Irrlicht.lib") 22#pragma comment(lib, "Irrlicht.lib")
23#endif 23#endif
24 24
25int main() 25int main()
26{ 26{
27 // ask if user would like shadows 27 // ask if user would like shadows
28 char i; 28 char i;
29 printf("Please press 'y' if you want to use realtime shadows.\n"); 29 printf("Please press 'y' if you want to use realtime shadows.\n");
30 30
31 std::cin >> i; 31 std::cin >> i;
32 32
33 const bool shadows = (i == 'y'); 33 const bool shadows = (i == 'y');
34 34
35 // ask user for driver 35 // ask user for driver
36 video::E_DRIVER_TYPE driverType=driverChoiceConsole(); 36 video::E_DRIVER_TYPE driverType=driverChoiceConsole();
37 if (driverType==video::EDT_COUNT) 37 if (driverType==video::EDT_COUNT)
38 return 1; 38 return 1;
39 39
40 40
41 /* 41 /*
42 Create device and exit if creation failed. We make the stencil flag 42 Create device and exit if creation failed. We make the stencil flag
43 optional to avoid slow screen modes for runs without shadows. 43 optional to avoid slow screen modes for runs without shadows.
44 */ 44 */
45 45
46 IrrlichtDevice *device = 46 IrrlichtDevice *device =
47 createDevice(driverType, core::dimension2d<u32>(640, 480), 47 createDevice(driverType, core::dimension2d<u32>(640, 480),
48 16, false, shadows); 48 16, false, shadows);
49 49
50 if (device == 0) 50 if (device == 0)
51 return 1; // could not create selected driver. 51 return 1; // could not create selected driver.
52 52
53 video::IVideoDriver* driver = device->getVideoDriver(); 53 video::IVideoDriver* driver = device->getVideoDriver();
54 scene::ISceneManager* smgr = device->getSceneManager(); 54 scene::ISceneManager* smgr = device->getSceneManager();
55 55
56 /* 56 /*
57 For our environment, we load a .3ds file. It is a small room I modelled 57 For our environment, we load a .3ds file. It is a small room I modelled
58 with Anim8or and exported into the 3ds format because the Irrlicht 58 with Anim8or and exported into the 3ds format because the Irrlicht
59 Engine does not support the .an8 format. I am a very bad 3d graphic 59 Engine does not support the .an8 format. I am a very bad 3d graphic
60 artist, and so the texture mapping is not very nice in this model. 60 artist, and so the texture mapping is not very nice in this model.
61 Luckily I am a better programmer than artist, and so the Irrlicht 61 Luckily I am a better programmer than artist, and so the Irrlicht
62 Engine is able to create a cool texture mapping for me: Just use the 62 Engine is able to create a cool texture mapping for me: Just use the
63 mesh manipulator and create a planar texture mapping for the mesh. If 63 mesh manipulator and create a planar texture mapping for the mesh. If
64 you want to see the mapping I made with Anim8or, uncomment this line. I 64 you want to see the mapping I made with Anim8or, uncomment this line. I
65 also did not figure out how to set the material right in Anim8or, it 65 also did not figure out how to set the material right in Anim8or, it
66 has a specular light color which I don't really like. I'll switch it 66 has a specular light color which I don't really like. I'll switch it
67 off too with this code. 67 off too with this code.
68 */ 68 */
69 69
70 scene::IAnimatedMesh* mesh = smgr->getMesh("../../media/room.3ds"); 70 scene::IAnimatedMesh* mesh = smgr->getMesh("../../media/room.3ds");
71 71
72 smgr->getMeshManipulator()->makePlanarTextureMapping(mesh->getMesh(0), 0.004f); 72 smgr->getMeshManipulator()->makePlanarTextureMapping(mesh->getMesh(0), 0.004f);
73 73
74 scene::ISceneNode* node = 0; 74 scene::ISceneNode* node = 0;
75 75
76 node = smgr->addAnimatedMeshSceneNode(mesh); 76 node = smgr->addAnimatedMeshSceneNode(mesh);
77 node->setMaterialTexture(0, driver->getTexture("../../media/wall.jpg")); 77 node->setMaterialTexture(0, driver->getTexture("../../media/wall.jpg"));
78 node->getMaterial(0).SpecularColor.set(0,0,0,0); 78 node->getMaterial(0).SpecularColor.set(0,0,0,0);
79 79
80 /* 80 /*
81 Now, for the first special effect: Animated water. It works like this: 81 Now, for the first special effect: Animated water. It works like this:
82 The WaterSurfaceSceneNode takes a mesh as input and makes it wave like 82 The WaterSurfaceSceneNode takes a mesh as input and makes it wave like
83 a water surface. And if we let this scene node use a nice material like 83 a water surface. And if we let this scene node use a nice material like
84 the EMT_REFLECTION_2_LAYER, it looks really cool. We are doing this 84 the EMT_REFLECTION_2_LAYER, it looks really cool. We are doing this
85 with the next few lines of code. As input mesh, we create a hill plane 85 with the next few lines of code. As input mesh, we create a hill plane
86 mesh, without hills. But any other mesh could be used for this, you 86 mesh, without hills. But any other mesh could be used for this, you
87 could even use the room.3ds (which would look really strange) if you 87 could even use the room.3ds (which would look really strange) if you
88 want to. 88 want to.
89 */ 89 */
90 90
91 mesh = smgr->addHillPlaneMesh( "myHill", 91 mesh = smgr->addHillPlaneMesh( "myHill",
92 core::dimension2d<f32>(20,20), 92 core::dimension2d<f32>(20,20),
93 core::dimension2d<u32>(40,40), 0, 0, 93 core::dimension2d<u32>(40,40), 0, 0,
94 core::dimension2d<f32>(0,0), 94 core::dimension2d<f32>(0,0),
95 core::dimension2d<f32>(10,10)); 95 core::dimension2d<f32>(10,10));
96 96
97 node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0), 3.0f, 300.0f, 30.0f); 97 node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0), 3.0f, 300.0f, 30.0f);
98 node->setPosition(core::vector3df(0,7,0)); 98 node->setPosition(core::vector3df(0,7,0));
99 99
100 node->setMaterialTexture(0, driver->getTexture("../../media/stones.jpg")); 100 node->setMaterialTexture(0, driver->getTexture("../../media/stones.jpg"));
101 node->setMaterialTexture(1, driver->getTexture("../../media/water.jpg")); 101 node->setMaterialTexture(1, driver->getTexture("../../media/water.jpg"));
102 102
103 node->setMaterialType(video::EMT_REFLECTION_2_LAYER); 103 node->setMaterialType(video::EMT_REFLECTION_2_LAYER);
104 104
105 /* 105 /*
106 The second special effect is very basic, I bet you saw it already in 106 The second special effect is very basic, I bet you saw it already in
107 some Irrlicht Engine demos: A transparent billboard combined with a 107 some Irrlicht Engine demos: A transparent billboard combined with a
108 dynamic light. We simply create a light scene node, let it fly around, 108 dynamic light. We simply create a light scene node, let it fly around,
109 and to make it look more cool, we attach a billboard scene node to it. 109 and to make it look more cool, we attach a billboard scene node to it.
110 */ 110 */
111 111
112 // create light 112 // create light
113 113
114 node = smgr->addLightSceneNode(0, core::vector3df(0,0,0), 114 node = smgr->addLightSceneNode(0, core::vector3df(0,0,0),
115 video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 800.0f); 115 video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 800.0f);
116 scene::ISceneNodeAnimator* anim = 0; 116 scene::ISceneNodeAnimator* anim = 0;
117 anim = smgr->createFlyCircleAnimator (core::vector3df(0,150,0),250.0f); 117 anim = smgr->createFlyCircleAnimator (core::vector3df(0,150,0),250.0f);
118 node->addAnimator(anim); 118 node->addAnimator(anim);
119 anim->drop(); 119 anim->drop();
120 120
121 // attach billboard to light 121 // attach billboard to light
122 122
123 node = smgr->addBillboardSceneNode(node, core::dimension2d<f32>(50, 50)); 123 node = smgr->addBillboardSceneNode(node, core::dimension2d<f32>(50, 50));
124 node->setMaterialFlag(video::EMF_LIGHTING, false); 124 node->setMaterialFlag(video::EMF_LIGHTING, false);
125 node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); 125 node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
126 node->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp")); 126 node->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp"));
127 127
128 /* 128 /*
129 The next special effect is a lot more interesting: A particle system. 129 The next special effect is a lot more interesting: A particle system.
130 The particle system in the Irrlicht Engine is quite modular and 130 The particle system in the Irrlicht Engine is quite modular and
131 extensible, but yet easy to use. There is a particle system scene node 131 extensible, but yet easy to use. There is a particle system scene node
132 into which you can put a particle emitter, which makes particles come out 132 into which you can put a particle emitter, which makes particles come out
133 of nothing. These emitters are quite flexible and usually have lots of 133 of nothing. These emitters are quite flexible and usually have lots of
134 parameters like direction, amount, and color of the particles they 134 parameters like direction, amount, and color of the particles they
135 create. 135 create.
136 136
137 There are different emitters, for example a point emitter which lets 137 There are different emitters, for example a point emitter which lets
138 particles pop out at a fixed point. If the particle emitters available 138 particles pop out at a fixed point. If the particle emitters available
139 in the engine are not enough for you, you can easily create your own 139 in the engine are not enough for you, you can easily create your own
140 ones, you'll simply have to create a class derived from the 140 ones, you'll simply have to create a class derived from the
141 IParticleEmitter interface and attach it to the particle system using 141 IParticleEmitter interface and attach it to the particle system using
142 setEmitter(). In this example we create a box particle emitter, which 142 setEmitter(). In this example we create a box particle emitter, which
143 creates particles randomly inside a box. The parameters define the box, 143 creates particles randomly inside a box. The parameters define the box,
144 direction of the particles, minimal and maximal new particles per 144 direction of the particles, minimal and maximal new particles per
145 second, color, and minimal and maximal lifetime of the particles. 145 second, color, and minimal and maximal lifetime of the particles.
146 146
147 Because only with emitters particle system would be a little bit 147 Because only with emitters particle system would be a little bit
148 boring, there are particle affectors which modify particles while 148 boring, there are particle affectors which modify particles while
149 they fly around. Affectors can be added to a particle system for 149 they fly around. Affectors can be added to a particle system for
150 simulating additional effects like gravity or wind. 150 simulating additional effects like gravity or wind.
151 The particle affector we use in this example is an affector which 151 The particle affector we use in this example is an affector which
152 modifies the color of the particles: It lets them fade out. Like the 152 modifies the color of the particles: It lets them fade out. Like the
153 particle emitters, additional particle affectors can also be 153 particle emitters, additional particle affectors can also be
154 implemented by you, simply derive a class from IParticleAffector and 154 implemented by you, simply derive a class from IParticleAffector and
155 add it with addAffector(). 155 add it with addAffector().
156 156
157 After we set a nice material to the particle system, we have a cool 157 After we set a nice material to the particle system, we have a cool
158 looking camp fire. By adjusting material, texture, particle emitter, 158 looking camp fire. By adjusting material, texture, particle emitter,
159 and affector parameters, it is also easily possible to create smoke, 159 and affector parameters, it is also easily possible to create smoke,
160 rain, explosions, snow, and so on. 160 rain, explosions, snow, and so on.
161 */ 161 */
162 162
163 // create a particle system 163 // create a particle system
164 164
165 scene::IParticleSystemSceneNode* ps = 165 scene::IParticleSystemSceneNode* ps =
166 smgr->addParticleSystemSceneNode(false); 166 smgr->addParticleSystemSceneNode(false);
167 167
168 scene::IParticleEmitter* em = ps->createBoxEmitter( 168 scene::IParticleEmitter* em = ps->createBoxEmitter(
169 core::aabbox3d<f32>(-7,0,-7,7,1,7), // emitter size 169 core::aabbox3d<f32>(-7,0,-7,7,1,7), // emitter size
170 core::vector3df(0.0f,0.06f,0.0f), // initial direction 170 core::vector3df(0.0f,0.06f,0.0f), // initial direction
171 80,100, // emit rate 171 80,100, // emit rate
172 video::SColor(0,255,255,255), // darkest color 172 video::SColor(0,255,255,255), // darkest color
173 video::SColor(0,255,255,255), // brightest color 173 video::SColor(0,255,255,255), // brightest color
174 800,2000,0, // min and max age, angle 174 800,2000,0, // min and max age, angle
175 core::dimension2df(10.f,10.f), // min size 175 core::dimension2df(10.f,10.f), // min size
176 core::dimension2df(20.f,20.f)); // max size 176 core::dimension2df(20.f,20.f)); // max size
177 177
178 ps->setEmitter(em); // this grabs the emitter 178 ps->setEmitter(em); // this grabs the emitter
179 em->drop(); // so we can drop it here without deleting it 179 em->drop(); // so we can drop it here without deleting it
180 180
181 scene::IParticleAffector* paf = ps->createFadeOutParticleAffector(); 181 scene::IParticleAffector* paf = ps->createFadeOutParticleAffector();
182 182
183 ps->addAffector(paf); // same goes for the affector 183 ps->addAffector(paf); // same goes for the affector
184 paf->drop(); 184 paf->drop();
185 185
186 ps->setPosition(core::vector3df(-70,60,40)); 186 ps->setPosition(core::vector3df(-70,60,40));
187 ps->setScale(core::vector3df(2,2,2)); 187 ps->setScale(core::vector3df(2,2,2));
188 ps->setMaterialFlag(video::EMF_LIGHTING, false); 188 ps->setMaterialFlag(video::EMF_LIGHTING, false);
189 ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); 189 ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
190 ps->setMaterialTexture(0, driver->getTexture("../../media/fire.bmp")); 190 ps->setMaterialTexture(0, driver->getTexture("../../media/fire.bmp"));
191 ps->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); 191 ps->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
192 192
193 /* 193 /*
194 Next we add a volumetric light node, which adds a glowing fake area light to 194 Next we add a volumetric light node, which adds a glowing fake area light to
195 the scene. Like with the billboards and particle systems we also assign a 195 the scene. Like with the billboards and particle systems we also assign a
196 texture for the desired effect, though this time we'll use a texture animator 196 texture for the desired effect, though this time we'll use a texture animator
197 to create the illusion of a magical glowing area effect. 197 to create the illusion of a magical glowing area effect.
198 */ 198 */
199 scene::IVolumeLightSceneNode * n = smgr->addVolumeLightSceneNode(0, -1, 199 scene::IVolumeLightSceneNode * n = smgr->addVolumeLightSceneNode(0, -1,
200 32, // Subdivisions on U axis 200 32, // Subdivisions on U axis
201 32, // Subdivisions on V axis 201 32, // Subdivisions on V axis
202 video::SColor(0, 255, 255, 255), // foot color 202 video::SColor(0, 255, 255, 255), // foot color
203 video::SColor(0, 0, 0, 0)); // tail color 203 video::SColor(0, 0, 0, 0)); // tail color
204 204
205 if (n) 205 if (n)
206 { 206 {
207 n->setScale(core::vector3df(56.0f, 56.0f, 56.0f)); 207 n->setScale(core::vector3df(56.0f, 56.0f, 56.0f));
208 n->setPosition(core::vector3df(-120,50,40)); 208 n->setPosition(core::vector3df(-120,50,40));
209 209
210 // load textures for animation 210 // load textures for animation
211 core::array<video::ITexture*> textures; 211 core::array<video::ITexture*> textures;
212 for (s32 g=7; g > 0; --g) 212 for (s32 g=7; g > 0; --g)
213 { 213 {
214 core::stringc tmp; 214 core::stringc tmp;
215 tmp = "../../media/portal"; 215 tmp = "../../media/portal";
216 tmp += g; 216 tmp += g;
217 tmp += ".bmp"; 217 tmp += ".bmp";
218 video::ITexture* t = driver->getTexture( tmp.c_str() ); 218 video::ITexture* t = driver->getTexture( tmp.c_str() );
219 textures.push_back(t); 219 textures.push_back(t);
220 } 220 }
221 221
222 // create texture animator 222 // create texture animator
223 scene::ISceneNodeAnimator* glow = smgr->createTextureAnimator(textures, 150); 223 scene::ISceneNodeAnimator* glow = smgr->createTextureAnimator(textures, 150);
224 224
225 // add the animator 225 // add the animator
226 n->addAnimator(glow); 226 n->addAnimator(glow);
227 227
228 // drop the animator because it was created with a create() function 228 // drop the animator because it was created with a create() function
229 glow->drop(); 229 glow->drop();
230 } 230 }
231 231
232 /* 232 /*
233 As our last special effect, we want a dynamic shadow be casted from an 233 As our last special effect, we want a dynamic shadow be casted from an
234 animated character. For this we load a DirectX .x model and place it 234 animated character. For this we load a DirectX .x model and place it
235 into our world. For creating the shadow, we simply need to call 235 into our world. For creating the shadow, we simply need to call
236 addShadowVolumeSceneNode(). The color of shadows is only adjustable 236 addShadowVolumeSceneNode(). The color of shadows is only adjustable
237 globally for all shadows, by calling ISceneManager::setShadowColor(). 237 globally for all shadows, by calling ISceneManager::setShadowColor().
238 Voila, here is our dynamic shadow. 238 Voila, here is our dynamic shadow.
239 239
240 Because the character is a little bit too small for this scene, we make 240 Because the character is a little bit too small for this scene, we make
241 it bigger using setScale(). And because the character is lighted by a 241 it bigger using setScale(). And because the character is lighted by a
242 dynamic light, we need to normalize the normals to make the lighting on 242 dynamic light, we need to normalize the normals to make the lighting on
243 it correct. This is always necessary if the scale of a dynamic lighted 243 it correct. This is always necessary if the scale of a dynamic lighted
244 model is not (1,1,1). Otherwise it would get too dark or too bright 244 model is not (1,1,1). Otherwise it would get too dark or too bright
245 because the normals will be scaled too. 245 because the normals will be scaled too.
246 */ 246 */
247 247
248 // add animated character 248 // add animated character
249 249
250 mesh = smgr->getMesh("../../media/dwarf.x"); 250 mesh = smgr->getMesh("../../media/dwarf.x");
251 scene::IAnimatedMeshSceneNode* anode = 0; 251 scene::IAnimatedMeshSceneNode* anode = 0;
252 252
253 anode = smgr->addAnimatedMeshSceneNode(mesh); 253 anode = smgr->addAnimatedMeshSceneNode(mesh);
254 anode->setPosition(core::vector3df(-50,20,-60)); 254 anode->setPosition(core::vector3df(-50,20,-60));
255 anode->setAnimationSpeed(15); 255 anode->setAnimationSpeed(15);
256 256
257 // add shadow 257 // add shadow
258 anode->addShadowVolumeSceneNode(); 258 anode->addShadowVolumeSceneNode();
259 smgr->setShadowColor(video::SColor(150,0,0,0)); 259 smgr->setShadowColor(video::SColor(150,0,0,0));
260 260
261 // make the model a little bit bigger and normalize its normals 261 // make the model a little bit bigger and normalize its normals
262 // because of the scaling, for correct lighting 262 // because of the scaling, for correct lighting
263 anode->setScale(core::vector3df(2,2,2)); 263 anode->setScale(core::vector3df(2,2,2));
264 anode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); 264 anode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
265 265
266 /* 266 /*
267 Finally we simply have to draw everything, that's all. 267 Finally we simply have to draw everything, that's all.
268 */ 268 */
269 269
270 scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(); 270 scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
271 camera->setPosition(core::vector3df(-50,50,-150)); 271 camera->setPosition(core::vector3df(-50,50,-150));
272 camera->setFarValue(10000.0f); // this increase a shadow visible range. 272 camera->setFarValue(10000.0f); // this increase a shadow visible range.
273 273
274 // disable mouse cursor 274 // disable mouse cursor
275 device->getCursorControl()->setVisible(false); 275 device->getCursorControl()->setVisible(false);
276 276
277 s32 lastFPS = -1; 277 s32 lastFPS = -1;
278 278
279 while(device->run()) 279 while(device->run())
280 if (device->isWindowActive()) 280 if (device->isWindowActive())
281 { 281 {
282 driver->beginScene(true, true, 0); 282 driver->beginScene(true, true, 0);
283 283
284 smgr->drawAll(); 284 smgr->drawAll();
285 285
286 driver->endScene(); 286 driver->endScene();
287 287
288 const s32 fps = driver->getFPS(); 288 const s32 fps = driver->getFPS();
289 289
290 if (lastFPS != fps) 290 if (lastFPS != fps)
291 { 291 {
292 core::stringw str = L"Irrlicht Engine - SpecialFX example ["; 292 core::stringw str = L"Irrlicht Engine - SpecialFX example [";
293 str += driver->getName(); 293 str += driver->getName();
294 str += "] FPS:"; 294 str += "] FPS:";
295 str += fps; 295 str += fps;
296 296
297 device->setWindowCaption(str.c_str()); 297 device->setWindowCaption(str.c_str());
298 lastFPS = fps; 298 lastFPS = fps;
299 } 299 }
300 } 300 }
301 301
302 device->drop(); 302 device->drop();
303 303
304 return 0; 304 return 0;
305} 305}
306 306
307/* 307/*
308**/ 308**/