Hi,
I'm playing with Irrlicht since a few weeks. I'm trying to add some text in my game so I used a ITextSceneNode with my own font and everything is fine, I can move it where I want.
I tried to rotate it as I rotate my others nodes using the "setRotation(vector3df&)" method and it doesn't work. So I read the code of CSpriteTextNode.cpp and I figured out that it called the Font->draw() method that doesn't take the RelativeRotation of my node into account (it seems that it projects my world coordinate to the absolute screen coordinate system and just draw it as it without applying any transformations).
So I want to add the possibility to draw text like ITextSceneNode does but with the use of basics transformation (rotation / scaling). I'm writing here to ask you how I can do that ?
I think about sub-classing CSpriteTextNode and change the render() method but it seems all the drawing stuff is done by "CGUIFont->draw()", what do you experts think about it ? Or maybe I'm completely missing something ?
Thanks for reading me, and thanks for Irrlicht (I'm quite new but the more I play with it, the more I like it).
Best way to rotate a ITextSceneNode
This should help ya.
Edit: this code works like you want it. But when using it with other render Targets. like my deferred renderer the text is flipped upside down. dunno why.
example usage:
Header:
Source:
Edit: this code works like you want it. But when using it with other render Targets. like my deferred renderer the text is flipped upside down. dunno why.
example usage:
Code: Select all
CTextNode* text = new CTextNode(gui, smgr->getRootSceneNode(), smgr);
text->setText("Hello my friend!");
text->setPosition(irr::core::vector3df(0,20,0));
Code: Select all
#ifndef CTEXTNODE_H
#define CTEXTNODE_H
#include <irrlicht.h>
class CTextNode : public irr::scene::ISceneNode
{
public:
/** Default constructor */
CTextNode(irr::gui::IGUIEnvironment* gui, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id=-1,
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),
const irr::core::vector3df& rotation = irr::core::vector3df(0,0,0),
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f));
/** Default destructor */
virtual ~CTextNode();
//SceneNode
void OnRegisterSceneNode(void);
void OnAnimate(irr::u32 timeMs);
void render(void);
const irr::core::aabbox3d<irr::f32>& getBoundingBox(void) const;
irr::video::SMaterial& getMaterial(irr::u32 num);
irr::u32 getMaterialCount() const;
void setText(const irr::c8* text);
void setColor(const irr::video::SColor& color);
protected:
irr::core::stringw Text;
irr::core::dimension2d<irr::u32> TextDimension;
irr::video::ITexture* TextTexture;
irr::video::SColor TextColor;
irr::scene::SMeshBuffer* MeshBuffer;
irr::video::SMaterial Material;
irr::core::aabbox3d<irr::f32> Box;
bool Redraw;
irr::gui::IGUIEnvironment* Gui;
private:
};
#endif // CTEXTNODE_H
Code: Select all
#include "irr/CTextNode.h"
CTextNode::CTextNode(irr::gui::IGUIEnvironment* gui, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position,
const irr::core::vector3df& rotation,
const irr::core::vector3df& scale) : irr::scene::ISceneNode(parent, mgr, id, position, rotation, scale)
{
//ctor
MeshBuffer = new irr::scene::SMeshBuffer;
MeshBuffer->Vertices.push_back(irr::video::S3DVertex(-0.5, 0.5, 0.0, 0.0, 0.0, -1.0, irr::video::SColor(255,255,255,255), 0.01, 0.01));
MeshBuffer->Vertices.push_back(irr::video::S3DVertex(0.5, 0.5, 0.0, 0.0, 0.0, -1.0, irr::video::SColor(255,255,255,255), 0.9999, 0.01));
MeshBuffer->Vertices.push_back(irr::video::S3DVertex(0.5, -0.5, 0.0, 0.0, 0.0, -1.0, irr::video::SColor(255,255,255,255), 0.9999, 0.9999));
MeshBuffer->Vertices.push_back(irr::video::S3DVertex(-0.5, -0.5, 0.0, 0.0, 0.0, -1.0, irr::video::SColor(255,255,255,255), 0.01, 0.9999));
MeshBuffer->Indices.push_back(0);
MeshBuffer->Indices.push_back(1);
MeshBuffer->Indices.push_back(2);
MeshBuffer->Indices.push_back(2);
MeshBuffer->Indices.push_back(3);
MeshBuffer->Indices.push_back(0);
MeshBuffer->recalculateBoundingBox();
Gui = gui;
TextTexture = NULL;
TextColor = irr::video::SColor(255,255,255,255);
Redraw = true;
Material.MaterialType = irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL;
Material.Lighting = false;
Material.BackfaceCulling = false;
}
CTextNode::~CTextNode()
{
//dtor
}
void CTextNode::setText(const irr::c8* text)
{
Text = text;
Redraw = true;
}
void CTextNode::setColor(const irr::video::SColor& color)
{
TextColor = color;
}
void CTextNode::OnRegisterSceneNode()
{
if (isVisible())
{
SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_TRANSPARENT);
if (Redraw)
{
SceneManager->getVideoDriver()->removeTexture(TextTexture);
TextDimension = Gui->getSkin()->getFont()->getDimension(Text.c_str());
irr::core::dimension2d<irr::u32> texdim = TextDimension;
texdim.Width += Gui->getSkin()->getFont()->getKerningWidth()+2;
texdim.Height += Gui->getSkin()->getFont()->getKerningHeight()+2;
if (TextDimension.Width != 0 && TextDimension.Height != 0)
{
TextTexture = SceneManager->getVideoDriver()->addRenderTargetTexture(texdim, "TextNodeTexture", irr::video::ECF_A8R8G8B8);
SceneManager->getVideoDriver()->setRenderTarget(TextTexture, true, true, irr::video::SColor(0,0,0,0));
SceneManager->getVideoDriver()->setMaterial(irr::video::SMaterial());
Gui->getSkin()->getFont()->draw(Text.c_str(), irr::core::rect<irr::s32>(0, 0, TextDimension.Width, TextDimension.Height), TextColor);
SceneManager->getVideoDriver()->setMaterial(irr::video::SMaterial());
SceneManager->getVideoDriver()->setRenderTarget(0, false, false);
SceneManager->getVideoDriver()->setMaterial(irr::video::SMaterial());
Material.setTexture(0, TextTexture);
}
Redraw = false;
}
}
irr::scene::ISceneNode::OnRegisterSceneNode();
}
void CTextNode::OnAnimate(irr::u32 timeMs)
{
irr::scene::ISceneNode::OnAnimate(timeMs);
}
void CTextNode::render(void)
{
irr::video::IVideoDriver* driver = SceneManager->getVideoDriver();
irr::core::matrix4 trans = getAbsoluteTransformation();
irr::core::matrix4 scale;
scale.setScale(irr::core::vector3df(TextDimension.Width, TextDimension.Height, 0.0));
trans *= scale;
driver->setTransform(irr::video::ETS_WORLD, trans);
driver->draw3DBox(getTransformedBoundingBox());
driver->setMaterial(Material);
driver->drawMeshBuffer(MeshBuffer);
driver->setMaterial(irr::video::SMaterial());
}
const irr::core::aabbox3d<irr::f32>& CTextNode::getBoundingBox(void) const
{
return MeshBuffer->getBoundingBox();
}
irr::video::SMaterial& CTextNode::getMaterial(irr::u32 num)
{
return Material;
}
irr::u32 CTextNode::getMaterialCount() const
{
return 1;
}
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Re:The text looks not clear on the screen.
Sudi wrote:This should help ya.
Edit: this code works like you want it. But when using it with other render Targets. like my deferred renderer the text is flipped upside down. dunno why.
example usage:Header:Code: Select all
CTextNode* text = new CTextNode(gui, smgr->getRootSceneNode(), smgr); text->setText("Hello my friend!"); text->setPosition(irr::core::vector3df(0,20,0));
Source:Code: Select all
#ifndef CTEXTNODE_H #define CTEXTNODE_H #include <irrlicht.h> class CTextNode : public irr::scene::ISceneNode { public: /** Default constructor */ CTextNode(irr::gui::IGUIEnvironment* gui, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id=-1, const irr::core::vector3df& position = irr::core::vector3df(0,0,0), const irr::core::vector3df& rotation = irr::core::vector3df(0,0,0), const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f)); /** Default destructor */ virtual ~CTextNode(); //SceneNode void OnRegisterSceneNode(void); void OnAnimate(irr::u32 timeMs); void render(void); const irr::core::aabbox3d<irr::f32>& getBoundingBox(void) const; irr::video::SMaterial& getMaterial(irr::u32 num); irr::u32 getMaterialCount() const; void setText(const irr::c8* text); void setColor(const irr::video::SColor& color); protected: irr::core::stringw Text; irr::core::dimension2d<irr::u32> TextDimension; irr::video::ITexture* TextTexture; irr::video::SColor TextColor; irr::scene::SMeshBuffer* MeshBuffer; irr::video::SMaterial Material; irr::core::aabbox3d<irr::f32> Box; bool Redraw; irr::gui::IGUIEnvironment* Gui; private: }; #endif // CTEXTNODE_H
Code: Select all
#include "irr/CTextNode.h" CTextNode::CTextNode(irr::gui::IGUIEnvironment* gui, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position, const irr::core::vector3df& rotation, const irr::core::vector3df& scale) : irr::scene::ISceneNode(parent, mgr, id, position, rotation, scale) { //ctor MeshBuffer = new irr::scene::SMeshBuffer; MeshBuffer->Vertices.push_back(irr::video::S3DVertex(-0.5, 0.5, 0.0, 0.0, 0.0, -1.0, irr::video::SColor(255,255,255,255), 0.01, 0.01)); MeshBuffer->Vertices.push_back(irr::video::S3DVertex(0.5, 0.5, 0.0, 0.0, 0.0, -1.0, irr::video::SColor(255,255,255,255), 0.9999, 0.01)); MeshBuffer->Vertices.push_back(irr::video::S3DVertex(0.5, -0.5, 0.0, 0.0, 0.0, -1.0, irr::video::SColor(255,255,255,255), 0.9999, 0.9999)); MeshBuffer->Vertices.push_back(irr::video::S3DVertex(-0.5, -0.5, 0.0, 0.0, 0.0, -1.0, irr::video::SColor(255,255,255,255), 0.01, 0.9999)); MeshBuffer->Indices.push_back(0); MeshBuffer->Indices.push_back(1); MeshBuffer->Indices.push_back(2); MeshBuffer->Indices.push_back(2); MeshBuffer->Indices.push_back(3); MeshBuffer->Indices.push_back(0); MeshBuffer->recalculateBoundingBox(); Gui = gui; TextTexture = NULL; TextColor = irr::video::SColor(255,255,255,255); Redraw = true; Material.MaterialType = irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL; Material.Lighting = false; Material.BackfaceCulling = false; } CTextNode::~CTextNode() { //dtor } void CTextNode::setText(const irr::c8* text) { Text = text; Redraw = true; } void CTextNode::setColor(const irr::video::SColor& color) { TextColor = color; } void CTextNode::OnRegisterSceneNode() { if (isVisible()) { SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_TRANSPARENT); if (Redraw) { SceneManager->getVideoDriver()->removeTexture(TextTexture); TextDimension = Gui->getSkin()->getFont()->getDimension(Text.c_str()); irr::core::dimension2d<irr::u32> texdim = TextDimension; texdim.Width += Gui->getSkin()->getFont()->getKerningWidth()+2; texdim.Height += Gui->getSkin()->getFont()->getKerningHeight()+2; if (TextDimension.Width != 0 && TextDimension.Height != 0) { TextTexture = SceneManager->getVideoDriver()->addRenderTargetTexture(texdim, "TextNodeTexture", irr::video::ECF_A8R8G8B8); SceneManager->getVideoDriver()->setRenderTarget(TextTexture, true, true, irr::video::SColor(0,0,0,0)); SceneManager->getVideoDriver()->setMaterial(irr::video::SMaterial()); Gui->getSkin()->getFont()->draw(Text.c_str(), irr::core::rect<irr::s32>(0, 0, TextDimension.Width, TextDimension.Height), TextColor); SceneManager->getVideoDriver()->setMaterial(irr::video::SMaterial()); SceneManager->getVideoDriver()->setRenderTarget(0, false, false); SceneManager->getVideoDriver()->setMaterial(irr::video::SMaterial()); Material.setTexture(0, TextTexture); } Redraw = false; } } irr::scene::ISceneNode::OnRegisterSceneNode(); } void CTextNode::OnAnimate(irr::u32 timeMs) { irr::scene::ISceneNode::OnAnimate(timeMs); } void CTextNode::render(void) { irr::video::IVideoDriver* driver = SceneManager->getVideoDriver(); irr::core::matrix4 trans = getAbsoluteTransformation(); irr::core::matrix4 scale; scale.setScale(irr::core::vector3df(TextDimension.Width, TextDimension.Height, 0.0)); trans *= scale; driver->setTransform(irr::video::ETS_WORLD, trans); driver->draw3DBox(getTransformedBoundingBox()); driver->setMaterial(Material); driver->drawMeshBuffer(MeshBuffer); driver->setMaterial(irr::video::SMaterial()); } const irr::core::aabbox3d<irr::f32>& CTextNode::getBoundingBox(void) const { return MeshBuffer->getBoundingBox(); } irr::video::SMaterial& CTextNode::getMaterial(irr::u32 num) { return Material; } irr::u32 CTextNode::getMaterialCount() const { return 1; }
Re: Best way to rotate a ITextSceneNode
jsyzljj: Did you change anything or just copy-paste a post here? Asking because new users which copy-paste posts are usually bots ... and right now I'm not sure yet if you are one or not (as your other posts looked rather normal...).
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
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Best way to rotate a ITextSceneNode
Seems it was just reposted to highlight code the C++ way, not as raw text