logo

Irrlicht3D tutoriál - Render to Texture

Po delší době Vám opět přináším volnější překlad dalšího oficiálního tutoriálu grafického C++ enginu Irrlicht.

Ukážeme si, jak renderovat scénu do textury. Render to texture (neboli RTT) je technologie často využívaná pro tvorbu různých speciálních efektů, využívá se například také při post-processingu obrazu. Jako bonus se také naučíme jak aktivovat spekulární highlighty (volně přeloženo “zrcadlové odrazy”).


Výsledný program
Výsledný program

Na začátku jako obvykle includneme hlavičkové soubory Irrlichtu, vytvoříme renderovací zařízení, atd.:

Kód:
#include <iostream>
#include <irrlicht.h>

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

int main()
{
  //nechme uživatele vybrat video 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_SOFTWARE2; break;
    case 'f': driverType = video::EDT_NULL;      break;
    default: return 1;
 
  } 

  //vytvoříme Irrlicht zařízení a v případě neúspěchu ukončíme program
  IrrlichtDevice *device = createDevice(driverType, core::dimension2d(640, 480),
  16, false, false);

  if (device == 0)
    return 1; //zařízení nemohlo být vytvořeno.

  video::IVideoDriver* driver = device->getVideoDriver();
  scene::ISceneManager* smgr = device->getSceneManager();
  gui::IGUIEnvironment* env = device->getGUIEnvironment();

Nyní načteme animovaný model faerie a vytvoříme mu scénový uzel. Novinkou je nastavení lesklosti materiálu na jinou hodnotu, než je 0 (což je výchozí nastavení). To aktivuje ty již zmíněné spekulární odrazy. Co stojí také za povšimnutí je, že zapínáme dynamické nasvětlování modelu, bez něj by nebyly žádné tyto světelné efekty možné.

Kód:
//načteme faerii a vytvoříme ji node
  scene::IAnimatedMeshSceneNode* fairy = smgr->addAnimatedMeshSceneNode(

  smgr->getMesh("../../media/faerie.md2"));

  if (fairy)
  {
    fairy->setMaterialTexture(0, 
      driver->getTexture("../../media/faerie2.bmp")); // nastavíme difuzní texturu

    fairy->setMaterialFlag(video::EMF_LIGHTING, true); // povolíme dynamické nasvětlování

    fairy->getMaterial(0).Shininess = 20.0f; // nastavíme velikost spekulárních odrazů

    fairy->setPosition(core::vector3df(-10,0,-100));

  }

Nyní musíme nastavit světla. Jedno přidáme přímo do blízkosti uzlu samotného a aby nebyl model celkově příliš tmavý (= tedy pro vykompenzování toho, že jsme na něm povolili dynamické nasvětlování), aktivujeme ambientní světlo scény. Ambientní světla nemají žádnou pevně danou pozici ani směr a ovlivňují rovnoměrně všechny objekty ve scéně.

Kód:
  //přidáme bílé světlo
  scene::ILightSceneNode* light = smgr->addLightSceneNode(0,
  core::vector3df(-15,5,-105), video::SColorf(1.0f, 1.0f, 1.0f));

  //nastavíme ambientní světlo
  driver->setAmbientLight(video::SColor(0,60,60,60));

Dalším bodem v kódu jsou klasické a dobře známé standardní úkony – přidání uživatelsky kontrolované kamery, vypnutí zobrazování kurzoru myši a přidání testovací krychle, kterou necháme pro oživení rotovat.

Kód:
  //přidáme FPS-style kameru
  scene::ICameraSceneNode* fpsCamera = smgr->addCameraSceneNodeFPS();

  fpsCamera->setPosition(core::vector3df(-50,50,-150));

  //zakážeme kurzor myši
  device->getCursorControl()->setVisible(false);

  //vytvoříme testovací krychli
  scene::ISceneNode* test = smgr->addCubeSceneNode(60);
  
  test->setPosition(core::vector3df(-100,0,-100));
  test->setMaterialFlag(video::EMF_LIGHTING, false); // zakážeme dynamická světla

  //vytvoříme rotační animátor krychle a zakážeme u ní dynamická světla
  scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator(
    core::vector3df(0.3f, 0.3f,0));

  test->addAnimator(anim);

  anim->drop();

  //nastavíme titulek okna
  device->setWindowCaption(
    L"Irrlicht Engine - Render to Texture and Specular Highlights example");

Pro otestování RTT potřebujeme nejdříve vytvořit speciální render target texturu. Ta není jako jiné, klasické textury, potřebujeme ji nejdříve ručně vytvořit. To uděláme zavoláním metody IvideoDriver::createRenderTargetTexture() a specifikováním jejích rozměrů. Vzhledem k tomu, že RTT sdílí ZBuffer s Vaším normálním video driverem, nepoužívejte rozměry větší, než má Váš aktuální frame buffer. (Pozn.: Pokud byste chtěli využívat větších RTT, existuje pro Irrlicht patch, který to umožňuje – pak hledejte na oficiálním fóru v Code Snippets.)
Protože nechceme renderovat do textury ze stejné pozice, jako má uživatel, přidáme další kameru, tentokrát již s fixní pozicí. Ještě před provedením těchto všech kroků ale pro jistotu ověříme, zda-li současný video driver podporuje RTT a pokud ne, zobrazíme varování.

Kód:
  //render target textura
  video::ITexture* rt = 0;

  scene::ICameraSceneNode* fixedCam = 0;

  if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
  {
    rt = driver->createRenderTargetTexture(core::dimension2d(256,256));

    test->setMaterialTexture(0, rt); //přiřadíme testovací krychli render target texturu

    //přidáme fixní kameru
    fixedCam = smgr->addCameraSceneNode(0, core::vector3df(10,10,-80),
      core::vector3df(-10,10,-100));

  }
  else
  {

    //vytvoříme varování v případě chyby
    gui::IGUISkin* skin = env->getSkin();

    gui::IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");

    if(font)
      skin->setFont(font);

    gui::IGUIStaticText* text = env->addStaticText(
      L"Your hardware or this renderer is not able to use the "\
      L"render to texture feature. RTT Disabled.",
      core::rect(150,20,470,60));

    text->setOverrideColor(video::SColor(100,255,255,255));
    
  }

Téměř hotovo. Nyní musíme vše vykreslit. Každý snímek budeme renderovat scénu dvakrát – jednou do textury, podruhé tak jak to běžně známe, přímo do okna naší aplikace. Před RTT renderováním ovšem nejdříve zakážeme viditelnost naší testovací krychle, protože sama má na sobě výslednou renderovací texturu.

Kód:
  while(device->run())
  {
    if (device->isWindowActive())
    {
      driver->beginScene(true, true, 0);
    
      if (rt)
      {
        //vykreslíme scénu do RTT
      
        //nastavíme render target na naší texturu
        driver->setRenderTarget(rt, true, true, video::SColor(0,0,0,255));     

        //zneviditelníme krychli a přepneme kameru
        test->setVisible(false);

        smgr->setActiveCamera(fixedCam);

        //vykreslíme celou scénu do render bufferu
        smgr->drawAll();                 

        //nastavíme původní render target
        driver->setRenderTarget(0);      

        //zviditelníme krychli a přepneme kameru zpět
        test->setVisible(true);
        smgr->setActiveCamera(fpsCamera);

      }

      //vykreslíme scénu normálním způsobem
      smgr->drawAll(); 
      env->drawAll();

      driver->endScene();

    }
    
  }

  if(rt)
    rt->drop(); //dropneme RTT protože jsme
    //ji vytvořili pomocí create() metody

  device->drop(); // dropneme Irrlicht zařízení

  return 0;

}

A to je pro dnešek vše - nyní už víte, jak používat RTT v Irrlichtu. :-)

Tento tutoriál je volnějším překladem oficiálního Irrlicht Engine tutoriálu Render To Texture. Můžete ho také nalézt na portálu Irrlicht3D.cz, jehož jsem spoluautorem.
 
Přidat do:

Komentáře:


U článku zatím nejsou žádné komentáře.
Buďte první!

Nový komentář

Nick:
E-mail:
Web:

Text komentáře:

Smajlíci: :-) :D :-)) ;) 8-) :-| :o ]:-> :P :( :O
Opište kód z obrázku prosím:
Captcha =>
(Je obrázek nečitelný ? Jednoduše na něj klikněte pravým tlačítkem a dejte načíst znovu!)

(HTML není povoleno, můžete však využít základních formátovacích BBCode značek)
Pro pohodlnější odesílání příspěvků je nutný zapnutý JavaScript.


Uživ. jméno:
Heslo:
Nemáte účet?
Zapomenuté heslo ?


V databázi není žádná aktivní anketa, sorry.

Webdesign, kódování a grafické návrhy

Výběr jazyka:
-

Stav na Jabberu:
Zjišťování ..

RSS výstupy:
Články RSS 2.0
Komentáře RSS 2.0


Running on rDragCZ CMS vers. 1.50 .. page generation took 131.05ms; generated on 07/02/12 .. Dostupnost měří: ServiceUptime.com .. Copyright 2009