Aktuelle Zeit: 29.04.2024, 12:21

Alle Zeiten sind UTC + 1 Stunde




Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
BeitragVerfasst: 21.09.2007, 13:20 
Offline
Newsposter
Benutzeravatar

Registriert: 12.03.2007, 10:42
Beiträge: 338
Wohnort: Berlin
Dieses Turotial sollzeigen wie man in Irrlicht Spezialeffekte erzeugt.
Unter anderrem wird gezeigt wie man stencil buffer shadows, das partikel system, billboards, dynamisches licht und das water surface scene node benutzt

Und so soll das ganze am ende dann aussehen:
Bild

Los geht's!

Wir Starten hier wie bei den letzten Tutorials, mit dem unterschied das wir das 'shadows' flag bei createDevice() auf true setzen.

Code:
#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("Bitte waehlen sie den Treiber aus den sie fuer dieses Programm benutzen wollen:\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_SOFTWARE2;break;
    case 'f': driverType = video::EDT_NULL;     break;
    default: return 1;
  }   

  // erstelle device und beende fals nicht erfolgreich
  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();


Als umgebung laden wir eine 3ds datei. Dieser wurde mal mit Anim8or Modeliert und ins 3ds format exportiert, da Irrlicht zu dem Zeitpunkt wo dieses Tutorial entstand noch keine .an8 dateien lesen konnte. Ausserdem is das Texture mapping nicht so schön. Wir gehen hier einfach mal davon aus das man ein besserer Programmierer als ein artist ist daher hilft uns Irrlicht beim erstellen eines Texture mapings. Einfach den mesh manipulator benutzen und eine planares texture mapping für das mesh erstellen.
Man wusste auch nicht wie man das Material in anim8or korrekt setzt. Ebenfals gibt es eine helle farbe(emessive color) die nicht so gemocht ist, daraufhin schalten wir dies auch gleich hier im code ab:
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).EmissiveColor.set(0,0,0,0);


Und nun der erste spezial effekt: Animiertes Wasser. Das ganze funktioniert wie folgt: Das WaterSurfaceSceneNode nutzt ein mesh als Vorlage und lässt es Wellen schlagen wie bei einer realen Wasser-Oberfläche. Und wenn wir bei diesem SceneNode MT_REFLECTION_2_LAYER benutzen, sieht das richtig gut aus. Und das ganze machen wir in den nächsten Code-Zeilen:
Als Grundmesh für das WaterSurfaceSceneNode erstellen wir ein hill plane mesh ohne die hügel und berge, aber man kann jedes beliebige Mesh dafür benutzen.
Code:
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);

Der zweite Spezialeffekt gehört wohl zu den Standard sachen. Diesen wirst du bestimmt schon in einigen Irrlicht-Engine Demos gesehen haben, ein Transparentes BillboardSceneNode kombiniert mit einem dynamischem licht. Wir erstellen ein simples lightSceneNode und lassen es umher fliegen und damit es noch ein wenig cooler aussieht hängen wir noch das billboardSceneNode dran.
Code:
// 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"));

Der nächste Spezialeffekt ist etwas interressanter, denn es ist ein Partikelsystem.
Das Partikelsystem der IrrlichtEngine ist frei modular und modifizierbar, dennoch ist es einfach zu benutzen.
Es gibt ein partikelSystemSceneNode welchem man so genannte emitter übergeben kann, diese bewirken dann zB. das Partikel aus dem Nichts auftauchen.
Diese emitter sind sehr flexibel und haben viele Parameter, wie zB Richtung, Menge und Farbe der zu erzeugenden Partikel.
Es gibt unterschiedliche emitter, so zB. gibt es den point-emitter der die Partikel von einem festem punkt aus erscheinen lässt.
Wenn einem die von Irrlicht vorgegebennen Partikel-emitter nicht genug sind, kann man sich eine von IParticleEmitter abgeletette klasse erstellen und diese dann mit setEmitter an das Partikel System übergeben.

In diesem Beispiel erstellen wir einen BoxPartikelEmitter der zufällig Partikel innerhalb einer Box erstellt.
Die Parameter definieren die Box, Richtung der Partikel, Mindeste und Maximale Anzahl neuer Partikel pro Sekunde, Farbe und Minimale und Maximale Lebenszeit der Partikel.

Aber nur mit einem emitter ist unser Partikelsystem ein wenig langweilig, es gibt benutzen wir auch noch particle affectors, diese modifizieren nämlich die Partikel während sie umherfliegen. Sie können zum Partikelsystem hinzugefügt werden und Simulieren zB. Gravitation und Wind. Den affector den wir in diesem Tutorial benutzen werden ist ein affector der die Farbe der Partikel verändert um genauer zu sein er erzeugt ein FadeOut. Wie auch bei den emittern kann man sich auch ein eigennen affector erstellen indem man eine neue klasse erstellt die von IParticleAffector abgeleitet ist und fügt diese mit addAffector zum Partikelsystem hinzu. Nachdem wir noch ein paar materials gesetzt haben, besitzen wir ein richtig toll aussehendes Lagerfeuer. Wenn man das material, die Textur, den partikel emitter und die affector parameter noch ein wenig modifiziert, ist es sogar möglich Rauch, Regen, Schnee, Explosionen usw. zu erstellen

Code:
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);


Als letzten Spezialeffekt wollen wir einen dynamischen Schatten von einem Animiertem Charakter erstellen. Dafür laden wir extra ein DirectX .x Model. Um einen Schatten zu erstellen müssen wir einfach nur addShadowVolumeSceneNode aufrufen. Die Farbe des Schattens kann man nur global, also für alle Schatten, verändern indem man ISceneManager::setShadowColor() aufruft. Und Voila, unser Schatten ist erzeugt.
Weil unser Charakter ein wenig klein für diese Szene ist, lassen wir ihn ein wenig grösser werden und rufen dafür setScale() auf. Und weil der Charakter von einem dynamischem Licht angeleuchtet wird, müssen die Normalen normalisiert werden damit das licht den Charakter korrekt beleuchtet. Das ist immer notwendig wenn man das model in seiner skalierung nicht (1,1,1) gesetzt ist. Andernfals wird es zu Dunkel oder zu Hell weil die Normalen auch Skaliert wurden.

Code:
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);

Und nun müssen wir nurnoch so wie immer alles Anzeigen.
Code:
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;
}


Zuletzt geändert von psyco001 am 27.10.2007, 19:29, insgesamt 16-mal geändert.

Nach oben
 Profil  
 
BeitragVerfasst: 21.09.2007, 13:33 
Offline
Moderator
Benutzeravatar

Registriert: 11.03.2007, 20:25
Beiträge: 556
Wohnort: Frankfurt/Main
haha^^
(diesen post lösch ich später)

_________________
yo. life's so bloody short.
Ihr dachtet Schulfernsehn sei die ultimative Folter? Falsch: Fahrstuhlmusik, extra leise.


Nach oben
 Profil  
 
BeitragVerfasst: 21.09.2007, 13:35 
Offline
Newsposter
Benutzeravatar

Registriert: 12.03.2007, 10:42
Beiträge: 338
Wohnort: Berlin
^^ backup *g*
das wär aber anz dolle emein von dir


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de