-
-
- We start like in some tutorials before. Please note that this time,
- the 'shadows' flag in createDevice() is set to true, for we want to
- have a dynamic shadow casted from an animated character. If your this
- example runs to slow, set it to false. The Irrlicht Engine checks
- if your hardware doesn't support the stencil buffer, and disables
- shadows by itself, but just in case the demo runs slow on your hardware.
-
-
- #include <irrlicht.h>
-#include <iostream>
-using namespace irr;
-
-#pragma comment(lib, "Irrlicht.lib")
-
-int main()
-{
- // ask user for driver video::E_DRIVER_TYPE driverType;
- printf("Please select the driver you want for this example:\n"\ " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\ " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\ " (f) NullDevice\n (otherKey) exit\n\n");
char i; std::cin >> i;
switch(i) { case 'a': driverType = video::EDT_DIRECT3D9;break; case 'b': driverType = video::EDT_DIRECT3D8;break; case 'c': driverType = video::EDT_OPENGL; break; case 'd': driverType = video::EDT_SOFTWARE; break; case 'e': driverType = video::EDT_BURNINGSVIDEO;break; case 'f': driverType = video::EDT_NULL; break; default: return 1; }
-
- // create device and exit if creation failed IrrlichtDevice *device = createDevice(driverType,
- core::dimension2d<s32>(640, 480), 16, false, true);
-
- if (device == 0)
- return 1;
-
- video::IVideoDriver* driver = device->getVideoDriver();
- scene::ISceneManager* smgr = device->getSceneManager();
-
- |
-
-
- For our environment, we load a .3ds file. It is a small room I modelled
- with Anim8or and exported it into the 3ds format because the Irrlicht
- Engine did not support the .an8 format when I wrote this tutorial.
- I am a very bad 3d graphic artist, and so the texture mapping is not
- very nice in this model. Luckily I am a better programmer than artist,
- and so the Irrlicht Engine is able to create a cool texture mapping
- for me: Just use the mesh manipulator and create a planar texture
- mapping for the mesh. If you want to see the mapping I made with Anim8or,
- uncomment this line. I also did not figure out how to
- set the material right in Anim8or, it has a specular light color
- which I don't really
- like. I'll switch it off too with this code.
-
-
- scene::IAnimatedMesh* mesh = smgr->getMesh(
- "../../media/room.3ds");
-
- smgr->getMeshManipulator()->makePlanarTextureMapping(
- mesh->getMesh(0), 0.008f);
-
- scene::ISceneNode* node = 0;
-
- node = smgr->addAnimatedMeshSceneNode(mesh);
- node->setMaterialTexture(0, driver->getTexture("../../media/wall.jpg"));
- node->getMaterial(0).SpecularColor.set(0,0,0,0); |
-
-
- Now, for the first special effect: Animated water. It works like
- this: The WaterSurfaceSceneNode takes a mesh as input and makes it
- wave like a water surface. And if we let this scene node use a nice
- material like the MT_REFLECTION_2_LAYER, it looks really cool. We
- are doing this with the next few lines of code. As input mesh, we
- create a hill plane mesh, without hills. But any other mesh could
- be used for this, you could even use the room.3ds (which would look
- really strange) if you wanted to.
-
-
- mesh = smgr->addHillPlaneMesh("myHill",
- core::dimension2d<f32>(20,20),
- core::dimension2d<s32>(40,40), 0, 0,
- core::dimension2d<f32>(0,0),
- core::dimension2d<f32>(10,10));
-
- node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0), 3.0f, 300.0f, 30.0f);
- node->setPosition(core::vector3df(0,7,0));
-
- node->setMaterialTexture(0, driver->getTexture("../../media/stones.jpg"));
- node->setMaterialTexture(1, driver->getTexture("../../media/water.jpg"));
-
- node->setMaterialType(video::EMT_REFLECTION_2_LAYER);
- |
-
-
- The second special effect is very basic, I bet you saw it already
- in some Irrlicht Engine demos: A transparent billboard combined with
- a dynamic light. We simply create a light scene node, let it fly around,
- an to make it look more cool, we attach a billboard scene node to
- it.
-
-
- // create light
-
- node = smgr->addLightSceneNode(0, core::vector3df(0,0,0),
- video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), 600.0f);
- scene::ISceneNodeAnimator* anim = 0;
- anim = smgr->createFlyCircleAnimator (core::vector3df(0,150,0),250.0f);
- node->addAnimator(anim);
- anim->drop();
-
- // attach billboard to light
-
- node = smgr->addBillboardSceneNode(node, core::dimension2d<f32>(50, 50));
- node->setMaterialFlag(video::EMF_LIGHTING, false);
- node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
- node->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp"));
-
- |
-
-
- The next special effect is a lot more interesting: A particle system.
- The particle system in the Irrlicht Engine is quit modular and extensible
- and yet easy to use. There is a particle system scene node into which
- you can put particle emitters, which make particles come out of nothing.
- These emitters are quite flexible and usually have lots of parameters
- like direction, amount and color of the particles they should create.
- There are different emitters, for example a point emitter which lets
- particles pop out at a fixed point. If the particle emitters available
- in the engine are not enough for you, you can easily create your own
- ones, you'll simply have to create a class derived from the IParticleEmitter
- interface and attach it to the particle system using setEmitter().
- In this example we create a box particle emitter, which creates particles
- randomly inside a box. The parameters define the box, direction of
- the particles, minimal and maximal new particles per second, color
- and minimal and maximal livetime of the particles.
- Because only with emitters particle system would be a little bit
- boring, there are particle affectors, which modify particles during
- they fly around. They can be added to the particle system, simulating
- additional effects like gravity or wind. The particle affector we
- use in this example is an affector, which modifies the color of the
- particles: It lets them fade out. Like the particle emitters, additional
- particle affectors can also be implemented by you, simply derive a
- class from IParticleAffector and add it with addAffector(). After
- we set a nice material to the particle system, we have a cool looking
- camp fire. By adjusting material, texture, particle emitter and affector
- parameters, it is also easily possible to create smoke, rain, explosions,
- snow, and so on.
-
-
-
-
- scene::IParticleSystemSceneNode* ps = 0;
- ps = smgr->addParticleSystemSceneNode(false);
- ps->setPosition(core::vector3df(-70,60,40));
- ps->setScale(core::vector3df(2,2,2));
-
- ps->setParticleSize(core::dimension2d<f32>(20.0f, 10.0f));
-
- scene::IParticleEmitter* em = ps->createBoxEmitter(
- core::aabbox3d<f32>(-7,0,-7,7,1,7),
- core::vector3df(0.0f,0.03f,0.0f),
- 80,100,
- video::SColor(0,255,255,255), video::SColor(0,255,255,255),
- 800,2000);
-
- ps->setEmitter(em);
- em->drop();
-
- scene::IParticleAffector* paf =
- ps->createFadeOutParticleAffector();
-
- ps->addAffector(paf);
- paf->drop();
-
- ps->setMaterialFlag(video::EMF_LIGHTING, false);
- ps->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
- ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA); |
-
-
- As our last special effect, we want a dynamic shadow be casted from
- an animated character. For this we load a DirectX .x model and place
- it into our world. For creating the shadow, we simply need to call addShadowVolumeSceneNode().
- The color of shadows is only adjustable globally for all shadows, by
- calling ISceneManager::setShadowColor(). Voila, here is our dynamic
- shadow.
- Because the character is a little bit too small for this scene, we make
- it bigger using setScale(). And because the character is lighted by
- a dynamic light, we need to normalize the normals to make the lighting
- on it correct. This is always necessary if the scale of a dynamic lighted
- model is not (1,1,1). Otherwise it would get too dark or too bright
- because the normals will be scaled too.
-
-
- mesh = smgr->getMesh("../../media/dwarf.x");
- scene::IAnimatedMeshSceneNode* anode = 0;
-
- anode = smgr->addAnimatedMeshSceneNode(mesh);
- anode->setPosition(core::vector3df(-50,20,-60));
- anode->setAnimationSpeed(15);
-
- // add shadow
- anode->addShadowVolumeSceneNode();
- smgr->setShadowColor(video::SColor(220,0,0,0));
-
- // make the model a little bit bigger and normalize its normals // because of this for correct lighting anode->setScale(core::vector3df(2,2,2)); anode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
|
-
-
- Finally we simply have to draw everything, that's all.
-
-
- scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
- camera->setPosition(core::vector3df(-50,50,-150));
-
-
- int lastFPS = -1;
-
- while(device->run())
- {
- driver->beginScene(true, true, 0);
-
- smgr->drawAll();
-
- driver->endScene();
-
- int fps = driver->getFPS();
-
- if (lastFPS != fps)
- {
- core::stringw str = L"Irrlicht Engine - SpecialFX example ["; str += driver->getName(); str += "] FPS:"; str += fps;
device->setWindowCaption(str.c_str()); lastFPS = fps; }
- }
-
- device->drop();
-
- return 0;
-}
-
-
- |
-
-
-
-
-
-
- |
-
-