Irrlicht 3D Engine
Tutorial 13: Render To Texture

This tutorial shows how to render to a texture using Irrlicht. Render to texture is a feature with which it is possible to create nice special effects. In addition, this tutorial shows how to enable specular highlights.

In the beginning, everything as usual. Include the needed headers, ask the user for the rendering driver, create the Irrlicht Device:

#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(driverType, core::dimension2d<u32>(640, 480),
16, false, false);
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();

Now, we load an animated mesh to be displayed. As in most examples, we'll take the fairy md2 model. The difference here: We set the shininess of the model to a value other than 0 which is the default value. This enables specular highlights on the model if dynamic lighting is on. The value influences the size of the highlights.

// load and display animated fairy mesh
scene::IAnimatedMeshSceneNode* fairy = smgr->addAnimatedMeshSceneNode(
smgr->getMesh("../../media/faerie.md2"));
if (fairy)
{
driver->getTexture("../../media/faerie2.bmp")); // set diffuse texture
fairy->setMaterialFlag(video::EMF_LIGHTING, true); // 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 );
}

To make specular highlights appear on the model, we need a dynamic light in the scene. We add one directly in vicinity of the model. In addition, to make the model not that dark, we set the ambient light to gray.

// add white light
smgr->addLightSceneNode(0, core::vector3df(-15,5,-105),
video::SColorf(1.0f, 1.0f, 1.0f));
// set ambient light
smgr->setAmbientLight(video::SColor(0,60,60,60));

The next is just some standard stuff: Add a test cube and let it rotate to make the scene more interesting. The user defined camera and cursor setup is made later on, right before the render loop.

// create test cube
scene::ISceneNode* test = smgr->addCubeSceneNode(60);
// let the cube rotate and set some light settings
scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator(
core::vector3df(0.3f, 0.3f,0));
test->setPosition(core::vector3df(-100,0,-100));
test->setMaterialFlag(video::EMF_LIGHTING, false); // disable dynamic lighting
test->addAnimator(anim);
anim->drop();
// set window caption
device->setWindowCaption(L"Irrlicht Engine - Render to Texture and Specular Highlights example");

To test out the render to texture feature, we need a render target texture. These are not like standard textures, but need to be created first. To create one, we call IVideoDriver::addRenderTargetTexture() and specify the size of the texture. Please don't use sizes bigger than the frame buffer for this, because the render target shares the zbuffer with the frame buffer. Because we want to render the scene not from the user camera into the texture, we add another fixed camera to the scene. But before we do all this, we check if the current running driver is able to render to textures. If it is not, we simply display a warning text.

// create render target
video::ITexture* rt = 0;
scene::ICameraSceneNode* fixedCam = 0;
{
rt = driver->addRenderTargetTexture(core::dimension2d<u32>(256,256), "RTT1");
test->setMaterialTexture(0, rt); // set material of cube to render target
// add fixed camera
fixedCam = smgr->addCameraSceneNode(0, core::vector3df(10,10,-80),
core::vector3df(-10,10,-100));
}
else
{
// create problem text
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<s32>(150,20,470,60));
text->setOverrideColor(video::SColor(100,255,255,255));
}
// add fps camera
scene::ICameraSceneNode* fpsCamera = smgr->addCameraSceneNodeFPS();
fpsCamera->setPosition(core::vector3df(-50,50,-150));
// disable mouse cursor
device->getCursorControl()->setVisible(false);

Nearly finished. Now we need to draw everything. Every frame, we draw the scene twice. Once from the fixed camera into the render target texture and once as usual. When rendering into the render target, we need to disable the visibility of the test cube, because it has the render target texture applied to it. That's it, wasn't too complicated I hope. :)

int lastFPS = -1;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0);
if (rt)
{
// draw scene into render target
// set render target texture
driver->setRenderTarget(rt, true, true, video::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(0, true, true, 0);
// 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;
}
irrlicht.h
Main header file of the irrlicht, the only file needed to include.
irr::scene::ISceneManager::addAnimatedMeshSceneNode
virtual IAnimatedMeshSceneNode * addAnimatedMeshSceneNode(IAnimatedMesh *mesh, ISceneNode *parent=0, s32 id=-1, const core::vector3df &position=core::vector3df(0, 0, 0), const core::vector3df &rotation=core::vector3df(0, 0, 0), const core::vector3df &scale=core::vector3df(1.0f, 1.0f, 1.0f), bool alsoAddIfMeshPointerZero=false)=0
Adds a scene node for rendering an animated mesh model.
irr::video::IVideoDriver::queryFeature
virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const =0
Queries the features of the driver.
irr::scene::ISceneManager::drawAll
virtual void drawAll()=0
Draws all the scene nodes.
irr::core::stringw
string< wchar_t > stringw
Typedef for wide character strings.
Definition: irrString.h:1361
irr::scene::ISceneManager::addCameraSceneNode
virtual ICameraSceneNode * addCameraSceneNode(ISceneNode *parent=0, const core::vector3df &position=core::vector3df(0, 0, 0), const core::vector3df &lookat=core::vector3df(0, 0, 100), s32 id=-1, bool makeActive=true)=0
Adds a camera scene node to the scene graph and sets it as active camera.
irr::gui::IGUIEnvironment::addStaticText
virtual IGUIStaticText * addStaticText(const wchar_t *text, const core::rect< s32 > &rectangle, bool border=false, bool wordWrap=true, IGUIElement *parent=0, s32 id=-1, bool fillBackground=false)=0
Adds a static text.
irr::scene::ISceneNode::setMaterialTexture
void setMaterialTexture(u32 textureLayer, video::ITexture *texture)
Sets the texture of the specified layer in all materials of this scene node to the new texture.
Definition: ISceneNode.h:436
irr::scene::ISceneManager::setAmbientLight
virtual void setAmbientLight(const video::SColorf &ambientColor)=0
Sets ambient color of the scene.
irr::IReferenceCounted::drop
bool drop() const
Drops the object. Decrements the reference counter by one.
Definition: IReferenceCounted.h:116
irr::scene::ISceneManager::getMesh
virtual IAnimatedMesh * getMesh(const io::path &filename)=0
Get pointer to an animateable mesh. Loads the file if not loaded already.
irr::video::IVideoDriver::getFPS
virtual s32 getFPS() const =0
Returns current frames per second value.
irr::scene::ISceneManager::addCubeSceneNode
virtual IMeshSceneNode * addCubeSceneNode(f32 size=10.0f, ISceneNode *parent=0, s32 id=-1, const core::vector3df &position=core::vector3df(0, 0, 0), const core::vector3df &rotation=core::vector3df(0, 0, 0), const core::vector3df &scale=core::vector3df(1.0f, 1.0f, 1.0f))=0
Adds a cube scene node.
irr::video::EDT_COUNT
@ EDT_COUNT
No driver, just for counting the elements.
Definition: EDriverTypes.h:56
irr::createDevice
IRRLICHT_API IrrlichtDevice *IRRCALLCONV createDevice(video::E_DRIVER_TYPE deviceType=video::EDT_SOFTWARE, const core::dimension2d< u32 > &windowSize=(core::dimension2d< u32 >(640, 480)), u32 bits=16, bool fullscreen=false, bool stencilbuffer=false, bool vsync=false, IEventReceiver *receiver=0)
Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.
irr::scene::ISceneNode::setPosition
virtual void setPosition(const core::vector3df &newpos)
Sets the position of the node relative to its parent.
Definition: ISceneNode.h:507
irr::video::IVideoDriver::beginScene
virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, SColor color=SColor(255, 0, 0, 0), const SExposedVideoData &videoData=SExposedVideoData(), core::rect< s32 > *sourceRect=0)=0
Applications must call this method before performing any rendering.
irr::gui::IGUIEnvironment::getSkin
virtual IGUISkin * getSkin() const =0
Returns pointer to the current gui skin.
irr::IrrlichtDevice
The Irrlicht device. You can create it with createDevice() or createDeviceEx().
Definition: IrrlichtDevice.h:43
irr::IrrlichtDevice::setWindowCaption
virtual void setWindowCaption(const wchar_t *text)=0
Sets the caption of the window.
irr::IrrlichtDevice::getCursorControl
virtual gui::ICursorControl * getCursorControl()=0
Provides access to the cursor control.
irr::gui::IGUIEnvironment::getFont
virtual IGUIFont * getFont(const io::path &filename)=0
Returns pointer to the font with the specified filename.
irr::video::EVDF_RENDER_TO_TARGET
@ EVDF_RENDER_TO_TARGET
Is driver able to render to a surface?
Definition: EDriverFeatures.h:17
irr::gui::IGUIStaticText::setOverrideColor
virtual void setOverrideColor(video::SColor color)=0
Sets another color for the text.
irr::IrrlichtDevice::isWindowActive
virtual bool isWindowActive() const =0
Returns if the window is active.
irr::core::dimension2d< u32 >
irr::scene::ISceneManager::setActiveCamera
virtual void setActiveCamera(ICameraSceneNode *camera)=0
Sets the currently active camera.
irr::IrrlichtDevice::getSceneManager
virtual scene::ISceneManager * getSceneManager()=0
Provides access to the scene manager.
irr::scene::ISceneManager::createRotationAnimator
virtual ISceneNodeAnimator * createRotationAnimator(const core::vector3df &rotationSpeed)=0
Creates a rotation animator, which rotates the attached scene node around itself.
irr::video::IVideoDriver::addRenderTargetTexture
virtual ITexture * addRenderTargetTexture(const core::dimension2d< u32 > &size, const io::path &name="rt", const ECOLOR_FORMAT format=ECF_UNKNOWN)=0
Adds a new render target texture to the texture cache.
irr::IrrlichtDevice::getVideoDriver
virtual video::IVideoDriver * getVideoDriver()=0
Provides access to the video driver for drawing 3d and 2d geometry.
irr::scene::ISceneManager::addCameraSceneNodeFPS
virtual ICameraSceneNode * addCameraSceneNodeFPS(ISceneNode *parent=0, f32 rotateSpeed=100.0f, f32 moveSpeed=0.5f, s32 id=-1, SKeyMap *keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false, f32 jumpSpeed=0.f, bool invertMouse=false, bool makeActive=true)=0
Adds a camera scene node with an animator which provides mouse and keyboard control appropriate for f...
irr
Everything in the Irrlicht Engine can be found in this namespace.
Definition: aabbox3d.h:12
driverChoice.h
irr::video::EMF_LIGHTING
@ EMF_LIGHTING
Will this material be lighted? Default: true.
Definition: EMaterialFlags.h:26
irr::gui::ICursorControl::setVisible
virtual void setVisible(bool visible)=0
Changes the visible state of the mouse cursor.
irr::scene::EMAT_STAND
@ EMAT_STAND
Definition: IAnimatedMeshMD2.h:18
irr::video::IVideoDriver::setRenderTarget
virtual bool setRenderTarget(video::ITexture *texture, bool clearBackBuffer=true, bool clearZBuffer=true, SColor color=video::SColor(0, 0, 0, 0))=0
Sets a new render target.
irr::gui::IGUIEnvironment::drawAll
virtual void drawAll()=0
Draws all gui elements by traversing the GUI environment starting at the root node.
irr::video::E_DRIVER_TYPE
E_DRIVER_TYPE
An enum for all types of drivers the Irrlicht Engine supports.
Definition: EDriverTypes.h:14
irr::scene::ISceneManager
The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff.
Definition: ISceneManager.h:150
irr::video::IVideoDriver::getTexture
virtual ITexture * getTexture(const io::path &filename)=0
Get access to a named texture.
irr::gui::IGUIEnvironment
GUI Environment. Used as factory and manager of all other GUI elements.
Definition: IGUIEnvironment.h:70
irr::core::vector3df
vector3d< f32 > vector3df
Typedef for a f32 3d vector.
Definition: vector3d.h:445
irr::video::IVideoDriver::endScene
virtual bool endScene()=0
Presents the rendered image to the screen.
irr::video::IVideoDriver
Interface to driver which is able to perform 2d and 3d graphics functions.
Definition: IVideoDriver.h:256
irr::IrrlichtDevice::getGUIEnvironment
virtual gui::IGUIEnvironment * getGUIEnvironment()=0
Provides access to the 2d user interface environment.
irr::IrrlichtDevice::run
virtual bool run()=0
Runs the device.
irr::scene::ISceneManager::addLightSceneNode
virtual ILightSceneNode * addLightSceneNode(ISceneNode *parent=0, const core::vector3df &position=core::vector3df(0, 0, 0), video::SColorf color=video::SColorf(1.0f, 1.0f, 1.0f), f32 radius=100.0f, s32 id=-1)=0
Adds a dynamic light scene node to the scene graph.