• Benvenuto in Making Videogames!
  • Dai sfogo alla tua fantasia!
  • Crea il tuo Videogioco!
Benvenuto ospite! Login Registrati




Valutazione discussione:
  • 1 voto(i) - 5 media
  • 1
  • 2
  • 3
  • 4
  • 5
Tutorial 13 - Render To Texture
#1
Tutorial 13: Render To Texture

[Immagine: 013shot.jpg]

Questo tutorial mostra come si fa un rendering verso una texture con Irrlicht. Il render verso texture è una feature con cui si possono creare effetti speciali molto interessanti. Inoltre nel tutorial verrà mostrato come si abilitano le specular highlights (luci speculari).
All'inizio tutto come al solito. Inclusione degli headers necessari e richiesta utente per la scelta del driver, quindi creazione del device di Irrlicht:
Codice PHP:
#include <irrlicht.h>
#include "driverChoice.h"

using namespace irr;

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif

int main()
{
    
// ask user for driver
    
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
    if (
driverType==video::EDT_COUNT)
        return 
1;

    
// create device and exit if creation failed

    
IrrlichtDevice *device =
        
createDevice(driverTypecore::dimension2d<u32>(640480),
        
16falsefalse);

    if (
device == 0)
        return 
1// could not create selected driver.

    
video::IVideoDriverdriver device->getVideoDriver();
    
scene::ISceneManagersmgr device->getSceneManager();
    
gui::IGUIEnvironmentenv device->getGUIEnvironment(); 
Ora carichiamo una mesh animata da visulaizzare. Come in altri esempi useremo il modello fairy.md2. La differenza stavolta è che impostiamo il valore di shininess (lucentezza) ad un valore diverso dal valore di default che è 0. Così facendo, avendo le luci dinamiche presenti, abilitiamo la specular highlights sul modello. Questo valore influenza la dimensione della luminescenza (highlights).
Codice PHP:
// load and display animated fairy mesh

    
scene::IAnimatedMeshSceneNodefairy smgr->addAnimatedMeshSceneNode(
        
smgr->getMesh("../../media/faerie.md2"));

    if (
fairy)
    {
        
fairy->setMaterialTexture(0,
                
driver->getTexture("../../media/faerie2.bmp")); // set diffuse texture
        
fairy->setMaterialFlag(video::EMF_LIGHTINGtrue); // enable dynamic lighting
        
fairy->getMaterial(0).Shininess 20.0f// set size of specular highlights
        
fairy->setPosition(core::vector3df(-10,0,-100));
        
fairy->setMD2Animation scene::EMAT_STAND );
    } 
Come detto per rendere visibile la luce speculare sul modello dobbiamo attivare una luce dinamica nella scena. Ne aggiungiamo in prossimità del modello. In aggiunta, per non rendere il modello troppo scuro, impostiamo una luce ambientale su un grigio chiaro.
Codice PHP:
// add white light
    
smgr->addLightSceneNode(0core::vector3df(-15,5,-105),
            
video::SColorf(1.0f1.0f1.0f));

    
// set ambient light
    
smgr->setAmbientLight(video::SColor(0,60,60,60)); 
Seguono operazioni standard: Aggiunta di un cubo rotante giusto per rendere la scena un po' più interessante. La camera e la gestione del cursore verranno fatte dopo, giusto prima del loop di render.
Codice PHP:
// create test cube
    
scene::ISceneNodetest smgr->addCubeSceneNode(60);

    
// let the cube rotate and set some light settings
    
scene::ISceneNodeAnimatoranim smgr->createRotationAnimator(
        
core::vector3df(0.3f0.3f,0));

    
test->setPosition(core::vector3df(-100,0,-100));
    
test->setMaterialFlag(video::EMF_LIGHTINGfalse); // disable dynamic lighting
    
test->addAnimator(anim);
    
anim->drop();

    
// set window caption
    
device->setWindowCaption(L"Irrlicht Engine - Render to Texture and Specular Highlights example"); 
Per testare il nostro render verso texture ci serve una texture che faccia da bersaglio per il nostro rendering. Dopodiché la applicheremo al cubo rotante. Non si tratta di texture standard, devono essere create appositamente. Per farlo dobbiamo chiamare IVideoDriver::addRenderTargetTexture() specificando la dimensione della texture stessa. Vi prego di annotare una cosa, non impostate mai la dimensione oltre la dimensione del frame buffer perché la texture per il rendering condivide lo zbuffer con lo stesso frame buffer. Poiché non vogliamo che il render sulla texture provenga dalla stessa camera dell'utente andiamo ad aggiungerne una seconda alla scena e sarà fissa. Ma prima di questo andiamo a controllare che il driver attivato sia in grado di effettuare un render su texture (oggi giorno è quasi inutile ndt). Se così non fosse mostriamo un testo di warning.
Codice PHP:
// create render target
    
video::ITexturert 0;
    
scene::ICameraSceneNodefixedCam 0;
    

    if (
driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
    {
        
rt driver->addRenderTargetTexture(core::dimension2d<u32>(256,256), "RTT1");
        
test->setMaterialTexture(0rt); // set material of cube to render target

        // add fixed camera
        
fixedCam smgr->addCameraSceneNode(0core::vector3df(10,10,-80),
            
core::vector3df(-10,10,-100));
    }
    else
    {
        
// create problem text
        
gui::IGUISkinskin env->getSkin();
        
gui::IGUIFontfont env->getFont("../../media/fonthaettenschweiler.bmp");
        if (
font)
            
skin->setFont(font);

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

        
text->setOverrideColor(video::SColor(100,255,255,255));
    }
    
    
// add fps camera
    
scene::ICameraSceneNodefpsCamera smgr->addCameraSceneNodeFPS();
    
fpsCamera->setPosition(core::vector3df(-50,50,-150));

    
// disable mouse cursor
    
device->getCursorControl()->setVisible(false); 
Abbiamo quasi finito. Ora dobbiamo disegnare il tutto. Ad ogni frame disegneremo al scena due volte. Una volta dalla camera fissa dentro la texture e poi come al solito con la camera utente. Quando renderizziamo nella texture, dobbiamo disabilitare la visibilità del cubo, questo perché su di esso è applicata la texture su cui renderizziamo. Questo è tutto, spero non sia stato troppo complicato Smile
Codice PHP:
int lastFPS = -1;

    while(
device->run())
    if (
device->isWindowActive())
    {
        
driver->beginScene(truetrue0);

        if (
rt)
        {
            
// draw scene into render target
            
            // set render target texture
            
driver->setRenderTarget(rttruetruevideo::SColor(0,0,0,255));

            
// make cube invisible and set fixed camera as active camera
            
test->setVisible(false);
            
smgr->setActiveCamera(fixedCam);

            
// draw whole scene into render buffer
            
smgr->drawAll();

            
// set back old render target
            // The buffer might have been distorted, so clear it
            
driver->setRenderTarget(0truetrue0);

            
// make the cube visible and set the user controlled camera as active one
            
test->setVisible(true);
            
smgr->setActiveCamera(fpsCamera);
        }
        
        
// draw scene normally
        
smgr->drawAll();
        
env->drawAll();

        
driver->endScene();

        
// display frames per second in window title
        
int fps driver->getFPS();
        if (
lastFPS != fps)
        {
            
core::stringw str L"Irrlicht Engine - Render to Texture and Specular Highlights example";
            
str += " FPS:";
            
str += fps;

            
device->setWindowCaption(str.c_str());
            
lastFPS fps;
        }
    }

    
device->drop(); // drop device
    
return 0;


Versione pdf scaricabile da QUI
 
Rispondi
  


Vai al forum:


Browsing: 1 Ospite(i)