Text in Irrlicht

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Donald Duck
Posts: 34
Joined: Sat Jan 21, 2017 6:51 pm
Location: Duckburg
Contact:

Text in Irrlicht

Post by Donald Duck »

I would like to make a sign with some text in Irrlicht. The text that I want to display on a sign is stored in a string. What can I use for this? I tried addBillboardTextSceneNode and addTextSceneNode, but the problem with these were that they rotated with the camera to always face the camera. That isn't realistic. I would like something that doesn't move compared to the rest of the scene no matter how I move the camera. How can I do this?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Text in Irrlicht

Post by CuteAlien »

You have to work with rendertarget textures (rtt's) for that. Meaning - you have a plane with a rtt on it. You set that texture as rendertarget and draw some text (usual text-drawing methods). Then the text will show up on that plane when it's rendered next. See RenderToTexture example for how to use rtt's (a short explanation - when using rtt's everything that usually would go to the screen will be put into a texture instead - and then you can use that texture again on models).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Donald Duck
Posts: 34
Joined: Sat Jan 21, 2017 6:51 pm
Location: Duckburg
Contact:

Re: Text in Irrlicht

Post by Donald Duck »

Could you please post an example code for how to do that?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Text in Irrlicht

Post by CuteAlien »

In the RenderToTexture example add the following line after the first smgr->drawAll();

Code: Select all

 
env->getSkin()->getFont()->draw(L"And the programmer rendered to texture\nand see it showed up on the model\nand everything was good.", core::recti(10, 10, 100, 20), irr::video::SColor(255, 255,255, 255));
 
edit: You can certainly also replace the drawAll() - then only the text shows. Basically everything that would go onto the screen usually will go the rtt when you have set one.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Donald Duck
Posts: 34
Joined: Sat Jan 21, 2017 6:51 pm
Location: Duckburg
Contact:

Re: Text in Irrlicht

Post by Donald Duck »

I can't get it to work in my code. I tried this and the cube was black:

Code: Select all

#include <irrlicht.h>
 
int main(){
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::EDT_OPENGL);
    irr::video::IVideoDriver *driver = device->getVideoDriver();
    irr::scene::ISceneManager *sceneManager = device->getSceneManager();
 
    irr::scene::IMeshSceneNode *mesh = sceneManager->addCubeSceneNode();
    mesh->setMaterialTexture(0, driver->addRenderTargetTexture(irr::core::dimension2d<irr::u32>(256,256), "RTT1"));
 
    sceneManager->addCameraSceneNode(0, irr::core::vector3df(50, 70, 50), irr::core::vector3df(0, 0, 0));
 
    while(device->run()){
        device->getVideoDriver()->beginScene(true, true, irr::video::SColor(255, 255, 255, 255));
        device->getGUIEnvironment()->getSkin()->getFont()->draw(L"And the programmer rendered to texture\nand see it showed up on the model\nand everything was good.", irr::core::recti(10, 10, 100, 20), irr::video::SColor(255, 255,255, 255));
        device->getSceneManager()->drawAll();
        device->getGUIEnvironment()->drawAll();
        device->getVideoDriver()->endScene();
    }
 
    return 0;
}
Image

What am I doing wrong?
MartinVee
Posts: 139
Joined: Tue Aug 02, 2016 3:38 pm
Location: Québec, Canada

Re: Text in Irrlicht

Post by MartinVee »

Like CuteAlien said, try it with the RenderToTarget tutorial.

Add the line :

Code: Select all

 
device->getGUIEnvironment()->getSkin()->getFont()->draw(L"And the programmer rendered to texture\nand see it showed up on the model\nand everything was good.", irr::core::recti(10, 10, 100, 20), irr::video::SColor(255, 255,255, 255));
 
... beween the line :

Code: Select all

 
// draw whole scene into render buffer
smgr->drawAll();
 
... and the line :

Code: Select all

 
// set back old render target
// The buffer might have been distorted, so clear it
driver->setRenderTarget(0, true, true, 0);
 
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Text in Irrlicht

Post by CuteAlien »

In your code you only create the rendertarget but never draw anything into it. You only do the normal rendering. You need to draw into that texture. The part in the example with the setRenderTarget stuff.

All those draw calls like font->draw(), scenemanager->drawAll, guiEnvironment->drawAll - they all draw into the currently set render target. Which by default is the screen. But you want to render the text first into a texture, that is why you have to set the texture as render-target. And then everything you draw will not end up in the screen but in that texture. And _then_ after you did draw into the texture you can use that texture to render to the screen (by setting the rendertarget back to 0 it will be back to drawing to screen).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Donald Duck
Posts: 34
Joined: Sat Jan 21, 2017 6:51 pm
Location: Duckburg
Contact:

Re: Text in Irrlicht

Post by Donald Duck »

Thanks, this code works:

Code: Select all

#include <irrlicht.h>
 
int main(){
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::EDT_OPENGL);
    irr::video::IVideoDriver *driver = device->getVideoDriver();
    irr::scene::ISceneManager *sceneManager = device->getSceneManager();
 
    irr::scene::IMeshSceneNode *mesh = sceneManager->addCubeSceneNode();
    irr::video::ITexture* rt = driver->addRenderTargetTexture(irr::core::dimension2d<irr::u32>(256,256), "RTT1");
    mesh->setMaterialTexture(0, rt);
    mesh->setMaterialFlag(irr::video::EMF_LIGHTING, false);
 
    sceneManager->addCameraSceneNode(0, irr::core::vector3df(50, 70, 50), irr::core::vector3df(0, 0, 0));
 
    while(device->run()){
        driver->beginScene(true, true, irr::video::SColor(255, 255, 255, 255));
        driver->setRenderTarget(rt, true, true, irr::video::SColor(0, 0, 0, 255));
        device->getGUIEnvironment()->getSkin()->getFont()->draw(L"And the programmer rendered to texture\nand see it showed up on the model\nand everything was good.", irr::core::recti(10, 10, 100, 20), irr::video::SColor(255, 255,255, 255));
        driver->setRenderTarget(0, true, true, irr::video::SColor(255, 255, 255, 255));
        sceneManager->drawAll();
        driver->endScene();
    }
 
    return 0;
}
Donald Duck
Posts: 34
Joined: Sat Jan 21, 2017 6:51 pm
Location: Duckburg
Contact:

Re: Text in Irrlicht

Post by Donald Duck »

I've also created a function that makes it simple to apply text as a texture on a 3D element:

texttexture.cpp:

Code: Select all

#include <irrlicht.h>
#include <map>
#include "texttexture.h"
 
std::map<irr::video::ITexture*, irr::core::stringw> textTextures;
 
void addTextToSceneNode(irr::scene::ISceneNode *sceneNode, irr::core::stringw text){
    irr::video::ITexture* rt = driver->addRenderTargetTexture(irr::core::dimension2d<irr::u32>(256,256));
    sceneNode->setMaterialTexture(0, rt);
    textTextures[rt] = text;
}
texttexture.h:

Code: Select all

#include <irrlicht.h>
#include <map>
 
void addTextToSceneNode(irr::scene::ISceneNode *sceneNode, irr::core::stringw text);
extern std::map<irr::video::ITexture*, irr::core::stringw> textTextures;
Irrlicht main loop:

Code: Select all

while(device->run()){
    driver->beginScene(true, true, irr::video::SColor(255, 255, 255, 255));
    for(std::map<irr::video::ITexture*, irr::core::stringw>::iterator it = textTextures.begin(); it != textTextures.end(); it++){
        driver->setRenderTarget(it->first, true, true, irr::video::SColor(0, 0, 0, 255));
        device->getGUIEnvironment()->getSkin()->getFont()->draw(it->second, irr::core::recti(10, 10, 100, 20), irr::video::SColor(255, 0, 0, 0));
    }
    driver->setRenderTarget(0, true, true, irr::video::SColor(255, 255, 255, 255));
    sceneManager->drawAll();
    driver->endScene();
}
To use this to draw a texture on a 3D element (for example a cube), use this code:

Code: Select all

irr::scene::ISceneNode *myCube = sceneManager->addCubeSceneNode(1);    //draw a cube
addTextToSceneNode(myCube, L"This example text will be drawn on the cube");    //draw some text on the cube
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Text in Irrlicht

Post by hendu »

You're drawing the text every frame there, just making sure you want to do that.
Post Reply