MovableText translation to MOGRE

Kodachi_Garou

14-11-2006 12:16:42

One of the most handy classes I found for Ogre was the MovableText class. It allowed rendering of text, pretty much like a TextAreaOverlay but fixing it to a given point in the world instead of fixed coordinates.

I'm currently trying to translate this class to work with MOGRE but I'm having some difficulties implementing MOGRE's interfaces.

The original source for the class is here: http://www.ogre3d.org/wiki/index.php/MovableText

As you can see, MovableText extends both MovableObject and Renderable, so in C# I started by inheriting from MovableObject and implementing IRenderable, for the multiple inheritance part.

However, the IRenderable interface looks somewhat strange in C#, with lots of bad declared methods and I have no idea how to implement the method stubs.

Any idea on how I could go about porting this code? It's a pretty useful class to have available to the managed world.

Cheers.

Bekas

14-11-2006 15:36:35

Extending Ogre classes is not supported yet, you'll be able to do it with next version of Mogre.

If you can't wait until then, here's what you should do:

-Get Mogre's source code
-Add this file in "include" folder:
#pragma once

#include "MogreSimpleRenderable.h"


/**
* File: MovableText.h
*
* description: This create create a billboarding object that display a text.
*
* @author 2003 by cTh see gavocanov@rambler.ru
* @update 2006 by barraq see nospam@barraquand.com
*/
namespace Ogre {

class MovableText : public SimpleRenderable
{
/******************************** MovableText data ****************************/
public:
enum HorizontalAlignment {H_LEFT, H_CENTER};
enum VerticalAlignment {V_BELOW, V_ABOVE};

protected:
String mFontName;
String mType;
String mName;
String mCaption;
HorizontalAlignment mHorizontalAlignment;
VerticalAlignment mVerticalAlignment;

ColourValue mColor;
RenderOperation mRenderOp;
AxisAlignedBox mAABB;
LightList mLList;

uint mCharHeight;
uint mSpaceWidth;

bool mNeedUpdate;
bool mUpdateColors;
bool mOnTop;

Real mTimeUntilNextToggle;
Real mRadius;
Real mAdditionalHeight;

Camera *mpCam;
RenderWindow *mpWin;
Font *mpFont;
MaterialPtr mpMaterial;
MaterialPtr mpBackgroundMaterial;

/******************************** public methods ******************************/
public:
MovableText(const String &name, const String &caption, const String &fontName = "BlueHighway", int charHeight = 32, const ColourValue &color = ColourValue::White);
virtual ~MovableText();

// Set settings
void setFontName(const String &fontName);
void setCaption(const String &caption);
void setColor(const ColourValue &color);
void setCharacterHeight(uint height);
void setSpaceWidth(uint width);
void setTextAlignment(const HorizontalAlignment& horizontalAlignment, const VerticalAlignment& verticalAlignment);
void setAdditionalHeight( Real height );
void showOnTop(bool show=true);

// Get settings
const String &getFontName() const {return mFontName;}
const String &getCaption() const {return mCaption;}
const ColourValue &getColor() const {return mColor;}

uint getCharacterHeight() const {return mCharHeight;}
uint getSpaceWidth() const {return mSpaceWidth;}
Real getAdditionalHeight() const {return mAdditionalHeight;}
bool getShowOnTop() const {return mOnTop;}
AxisAlignedBox GetAABB(void) { return mAABB; }

/******************************** protected methods and overload **************/
protected:

// from MovableText, create the object
void _setupGeometry();
void _updateColors();

// from MovableObject
void getWorldTransforms(Matrix4 *xform) const;
Real getBoundingRadius(void) const {return mRadius;};
Real getSquaredViewDepth(const Camera *cam) const {return 0;};
const Quaternion &getWorldOrientation(void) const;
const Vector3 &getWorldPosition(void) const;
const AxisAlignedBox &getBoundingBox(void) const {return mAABB;};
const String &getName(void) const {return mName;};
const String &getMovableType(void) const {static Ogre::String movType = "MovableText"; return movType;};

void _notifyCurrentCamera(Camera *cam);
void _updateRenderQueue(RenderQueue* queue);

// from renderable
void getRenderOperation(RenderOperation &op);
const MaterialPtr &getMaterial(void) const {assert(!mpMaterial.isNull());return mpMaterial;};
const LightList &getLights(void) const {return mLList;};
};

}


namespace Mogre
{

public ref class MovableText : public SimpleRenderable
{
/******************************** MovableText data ****************************/
public:
enum class HorizontalAlignment {H_LEFT, H_CENTER};
enum class VerticalAlignment {V_BELOW, V_ABOVE};

/******************************** public methods ******************************/
public:
MovableText(String^ name, String^ caption, String^ fontName, int charHeight, ColourValue color)
: SimpleRenderable( _ctor(name, caption, fontName, charHeight, color) )
{
_createdByCLR = true;
}

MovableText(String^ name, String^ caption, String^ fontName, int charHeight)
: SimpleRenderable( _ctor(name, caption, fontName, charHeight, ColourValue::White) )
{
_createdByCLR = true;
}

MovableText(String^ name, String^ caption, String^ fontName)
: SimpleRenderable( _ctor(name, caption, fontName, 32, ColourValue::White) )
{
_createdByCLR = true;
}

MovableText(String^ name, String^ caption)
: SimpleRenderable( _ctor(name, caption, "BlueHighway", 32, ColourValue::White) )
{
_createdByCLR = true;
}

property String^ FontName
{
String^ get()
{
return TO_CLR_STRING( static_cast<Ogre::MovableText*>(_native)->getFontName() );
}
void set(String^ value)
{
DECLARE_OGRE_STRING(o_value, value)
static_cast<Ogre::MovableText*>(_native)->setFontName(o_value);
}
}

property String^ Caption
{
String^ get()
{
return TO_CLR_STRING( static_cast<Ogre::MovableText*>(_native)->getCaption() );
}
void set(String^ value)
{
DECLARE_OGRE_STRING(o_value, value)
static_cast<Ogre::MovableText*>(_native)->setCaption(o_value);
}
}

property ColourValue Color
{
ColourValue get()
{
return static_cast<Ogre::MovableText*>(_native)->getColor();
}
void set(ColourValue value)
{
static_cast<Ogre::MovableText*>(_native)->setColor( value );
}
}

property Ogre::uint CharacterHeight
{
Ogre::uint get()
{
return static_cast<Ogre::MovableText*>(_native)->getCharacterHeight();
}
void set(Ogre::uint value)
{
static_cast<Ogre::MovableText*>(_native)->setCharacterHeight( value );
}
}

property Ogre::uint SpaceWidth
{
Ogre::uint get()
{
return static_cast<Ogre::MovableText*>(_native)->getSpaceWidth();
}
void set(Ogre::uint value)
{
static_cast<Ogre::MovableText*>(_native)->setSpaceWidth( value );
}
}

property Ogre::Real AdditionalHeight
{
Ogre::Real get()
{
return static_cast<Ogre::MovableText*>(_native)->getAdditionalHeight();
}
void set(Ogre::Real value)
{
static_cast<Ogre::MovableText*>(_native)->setAdditionalHeight( value );
}
}

property bool ShowOnTop
{
bool get()
{
return static_cast<Ogre::MovableText*>(_native)->getShowOnTop();
}
void set(bool value)
{
static_cast<Ogre::MovableText*>(_native)->showOnTop( value );
}
}

void SetTextAlignment(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment)
{
static_cast<Ogre::MovableText*>(_native)->setTextAlignment( (Ogre::MovableText::HorizontalAlignment)horizontalAlignment, (Ogre::MovableText::VerticalAlignment)verticalAlignment);
}

AxisAlignedBox^ GetAABB()
{
return static_cast<Ogre::MovableText*>(_native)->GetAABB();
}

private:
// Called by all the constructors
Ogre::MovableText* _ctor(String^ name, String^ caption, String^ fontName, int charHeight, ColourValue color)
{
DECLARE_OGRE_STRING(o_name, name)
DECLARE_OGRE_STRING(o_caption, caption)
DECLARE_OGRE_STRING(o_fontName, fontName)

return new Ogre::MovableText(o_name, o_caption, o_fontName, charHeight, color);
}
};
}


-Add this file in "src" folder:
/**
* File: MovableText.cpp
*
* description: This create create a billboarding object that display a text.
*
* @author 2003 by cTh see gavocanov@rambler.ru
* @update 2006 by barraq see nospam@barraquand.com
*/

#include "stdafx.h"
#include "MovableText.h"

using namespace Ogre;

#define POS_TEX_BINDING 0
#define COLOUR_BINDING 1

MovableText::MovableText(const Ogre::String &name, const Ogre::String &caption, const Ogre::String &fontName, int charHeight, const ColourValue &color)
: mpCam(NULL)
, mpWin(NULL)
, mpFont(NULL)
, mName(name)
, mCaption(caption)
, mFontName(fontName)
, mCharHeight(charHeight)
, mColor(color)
, mType("MovableText")
, mTimeUntilNextToggle(0)
, mSpaceWidth(0)
, mUpdateColors(true)
, mOnTop(false)
, mHorizontalAlignment(H_LEFT)
, mVerticalAlignment(V_BELOW)
, mAdditionalHeight(0.0)
{
if (name == "")
Exception(Exception::ERR_INVALIDPARAMS, "Trying to create MovableText without name", "MovableText::MovableText");

if (caption == "")
Exception(Exception::ERR_INVALIDPARAMS, "Trying to create MovableText without caption", "MovableText::MovableText");

mRenderOp.vertexData = NULL;
this->setFontName(mFontName);
this->_setupGeometry();
}

MovableText::~MovableText()
{
if (mRenderOp.vertexData)
delete mRenderOp.vertexData;
}

void MovableText::setFontName(const Ogre::String &fontName)
{
if((Ogre::MaterialManager::getSingletonPtr()->resourceExists(mName + "Material")))
{
Ogre::MaterialManager::getSingleton().remove(mName + "Material");
}

if (mFontName != fontName || mpMaterial.isNull() || !mpFont)
{
mFontName = fontName;
mpFont = (Font *)FontManager::getSingleton().getByName(mFontName).getPointer();
if (!mpFont)
Exception(Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + fontName, "MovableText::setFontName");

mpFont->load();
if (!mpMaterial.isNull())
{
MaterialManager::getSingletonPtr()->remove(mpMaterial->getName());
mpMaterial.setNull();
}

mpMaterial = mpFont->getMaterial()->clone(mName + "Material");
if (!mpMaterial->isLoaded())
mpMaterial->load();

mpMaterial->setDepthCheckEnabled(!mOnTop);
mpMaterial->setDepthBias(!mOnTop);
mpMaterial->setDepthWriteEnabled(mOnTop);
mpMaterial->setLightingEnabled(false);
mNeedUpdate = true;
}
}

void MovableText::setCaption(const Ogre::String &caption)
{
if (caption != mCaption)
{
mCaption = caption;
mNeedUpdate = true;
}
}

void MovableText::setColor(const ColourValue &color)
{
if (color != mColor)
{
mColor = color;
mUpdateColors = true;
}
}

void MovableText::setCharacterHeight(uint height)
{
if (height != mCharHeight)
{
mCharHeight = height;
mNeedUpdate = true;
}
}

void MovableText::setSpaceWidth(uint width)
{
if (width != mSpaceWidth)
{
mSpaceWidth = width;
mNeedUpdate = true;
}
}

void MovableText::setTextAlignment(const HorizontalAlignment& horizontalAlignment, const VerticalAlignment& verticalAlignment)
{
if(mHorizontalAlignment != horizontalAlignment)
{
mHorizontalAlignment = horizontalAlignment;
mNeedUpdate = true;
}
if(mVerticalAlignment != verticalAlignment)
{
mVerticalAlignment = verticalAlignment;
mNeedUpdate = true;
}
}

void MovableText::setAdditionalHeight( Real height )
{
if( mAdditionalHeight != height )
{
mAdditionalHeight = height;
mNeedUpdate = true;
}
}

void MovableText::showOnTop(bool show)
{
if( mOnTop != show && !mpMaterial.isNull() )
{
mOnTop = show;
mpMaterial->setDepthBias(!mOnTop);
mpMaterial->setDepthCheckEnabled(!mOnTop);
mpMaterial->setDepthWriteEnabled(mOnTop);
}
}

void MovableText::_setupGeometry()
{
assert(mpFont);
assert(!mpMaterial.isNull());

uint vertexCount = static_cast<uint>(mCaption.size() * 6);

if (mRenderOp.vertexData)
{
// Removed this test as it causes problems when replacing a caption
// of the same size: replacing "Hello" with "hello"
// as well as when changing the text alignment
//if (mRenderOp.vertexData->vertexCount != vertexCount)
{
delete mRenderOp.vertexData;
mRenderOp.vertexData = NULL;
mUpdateColors = true;
}
}

if (!mRenderOp.vertexData)
mRenderOp.vertexData = new VertexData();

mRenderOp.indexData = 0;
mRenderOp.vertexData->vertexStart = 0;
mRenderOp.vertexData->vertexCount = vertexCount;
mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
mRenderOp.useIndexes = false;

VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding;
size_t offset = 0;

// create/bind positions/tex.ccord. buffer
if (!decl->findElementBySemantic(VES_POSITION))
decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);

offset += VertexElement::getTypeSize(VET_FLOAT3);

if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES))
decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);

HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING),
mRenderOp.vertexData->vertexCount,
HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
bind->setBinding(POS_TEX_BINDING, ptbuf);

// Colours - store these in a separate buffer because they change less often
if (!decl->findElementBySemantic(VES_DIFFUSE))
decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);

HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING),
mRenderOp.vertexData->vertexCount,
HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
bind->setBinding(COLOUR_BINDING, cbuf);

size_t charlen = mCaption.size();
Real *pPCBuff = static_cast<Real*>(ptbuf->lock(HardwareBuffer::HBL_DISCARD));

float largestWidth = 0;
float left = 0 * 2.0 - 1.0;
float top = -((0 * 2.0) - 1.0);

// Derive space width from a capital A
if (mSpaceWidth == 0)
mSpaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0;

// for calculation of AABB
Ogre::Vector3 min, max, currPos;
Ogre::Real maxSquaredRadius;
bool first = true;

// Use iterator
Ogre::String::iterator i, iend;
iend = mCaption.end();
bool newLine = true;
Real len = 0.0f;

if(mVerticalAlignment == MovableText::V_ABOVE)
{
// Raise the first line of the caption
top += mCharHeight;
for (i = mCaption.begin(); i != iend; ++i)
{
if (*i == '\n')
top += mCharHeight * 2.0;
}
}

for (i = mCaption.begin(); i != iend; ++i)
{
if (newLine)
{
len = 0.0f;
for (Ogre::String::iterator j = i; j != iend && *j != '\n'; j++)
{
if (*j == ' ')
len += mSpaceWidth;
else
len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0;
}
newLine = false;
}

if (*i == '\n')
{
left = 0 * 2.0 - 1.0;
top -= mCharHeight * 2.0;
newLine = true;
continue;
}

if (*i == ' ')
{
// Just leave a gap, no tris
left += mSpaceWidth;
// Also reduce tri count
mRenderOp.vertexData->vertexCount -= 6;
continue;
}

Real horiz_height = mpFont->getGlyphAspectRatio(*i);
Real u1, u2, v1, v2;
mpFont->getGlyphTexCoords(*i, u1, v1, u2, v2);

// each vert is (x, y, z, u, v)
//-------------------------------------------------------------------------------------
// First tri
//
// Upper left
if(mHorizontalAlignment == MovableText::H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2);
*pPCBuff++ = top;
*pPCBuff++ = -1.0;
*pPCBuff++ = u1;
*pPCBuff++ = v1;

// Deal with bounds
if(mHorizontalAlignment == MovableText::H_LEFT)
currPos = Ogre::Vector3(left, top, -1.0);
else
currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
if (first)
{
min = max = currPos;
maxSquaredRadius = currPos.squaredLength();
first = false;
}
else
{
min.makeFloor(currPos);
max.makeCeil(currPos);
maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
}

top -= mCharHeight * 2.0;

// Bottom left
if(mHorizontalAlignment == MovableText::H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2);
*pPCBuff++ = top;
*pPCBuff++ = -1.0;
*pPCBuff++ = u1;
*pPCBuff++ = v2;

// Deal with bounds
if(mHorizontalAlignment == MovableText::H_LEFT)
currPos = Ogre::Vector3(left, top, -1.0);
else
currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
min.makeFloor(currPos);
max.makeCeil(currPos);
maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

top += mCharHeight * 2.0;
left += horiz_height * mCharHeight * 2.0;

// Top right
if(mHorizontalAlignment == MovableText::H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2);
*pPCBuff++ = top;
*pPCBuff++ = -1.0;
*pPCBuff++ = u2;
*pPCBuff++ = v1;
//-------------------------------------------------------------------------------------

// Deal with bounds
if(mHorizontalAlignment == MovableText::H_LEFT)
currPos = Ogre::Vector3(left, top, -1.0);
else
currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
min.makeFloor(currPos);
max.makeCeil(currPos);
maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

//-------------------------------------------------------------------------------------
// Second tri
//
// Top right (again)
if(mHorizontalAlignment == MovableText::H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2);
*pPCBuff++ = top;
*pPCBuff++ = -1.0;
*pPCBuff++ = u2;
*pPCBuff++ = v1;

currPos = Ogre::Vector3(left, top, -1.0);
min.makeFloor(currPos);
max.makeCeil(currPos);
maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

top -= mCharHeight * 2.0;
left -= horiz_height * mCharHeight * 2.0;

// Bottom left (again)
if(mHorizontalAlignment == MovableText::H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2);
*pPCBuff++ = top;
*pPCBuff++ = -1.0;
*pPCBuff++ = u1;
*pPCBuff++ = v2;

currPos = Ogre::Vector3(left, top, -1.0);
min.makeFloor(currPos);
max.makeCeil(currPos);
maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

left += horiz_height * mCharHeight * 2.0;

// Bottom right
if(mHorizontalAlignment == MovableText::H_LEFT)
*pPCBuff++ = left;
else
*pPCBuff++ = left - (len / 2);
*pPCBuff++ = top;
*pPCBuff++ = -1.0;
*pPCBuff++ = u2;
*pPCBuff++ = v2;
//-------------------------------------------------------------------------------------

currPos = Ogre::Vector3(left, top, -1.0);
min.makeFloor(currPos);
max.makeCeil(currPos);
maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

// Go back up with top
top += mCharHeight * 2.0;

float currentWidth = (left + 1)/2 - 0;
if (currentWidth > largestWidth)
largestWidth = currentWidth;
}

// Unlock vertex buffer
ptbuf->unlock();

// update AABB/Sphere radius
mAABB = Ogre::AxisAlignedBox(min, max);
mRadius = Ogre::Math::Sqrt(maxSquaredRadius);

if (mUpdateColors)
this->_updateColors();

mNeedUpdate = false;
}

void MovableText::_updateColors(void)
{
assert(mpFont);
assert(!mpMaterial.isNull());

// Convert to system-specific
RGBA color;
Root::getSingleton().convertColourValue(mColor, &color);
HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING);
RGBA *pDest = static_cast<RGBA*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
for (uint i = 0; i < mRenderOp.vertexData->vertexCount; ++i)
*pDest++ = color;
vbuf->unlock();
mUpdateColors = false;
}

const Quaternion& MovableText::getWorldOrientation(void) const
{
assert(mpCam);
return const_cast<Quaternion&>(mpCam->getDerivedOrientation());
}

const Vector3& MovableText::getWorldPosition(void) const
{
assert(mParentNode);
return mParentNode->_getDerivedPosition();
}

void MovableText::getWorldTransforms(Matrix4 *xform) const
{
if (this->isVisible() && mpCam)
{
Matrix3 rot3x3, scale3x3 = Matrix3::IDENTITY;

// store rotation in a matrix
mpCam->getDerivedOrientation().ToRotationMatrix(rot3x3);

// parent node position
Vector3 ppos = mParentNode->_getDerivedPosition() + Vector3::UNIT_Y*mAdditionalHeight;

// apply scale
scale3x3[0][0] = mParentNode->_getDerivedScale().x / 2;
scale3x3[1][1] = mParentNode->_getDerivedScale().y / 2;
scale3x3[2][2] = mParentNode->_getDerivedScale().z / 2;

// apply all transforms to xform
*xform = (rot3x3 * scale3x3);
xform->setTrans(ppos);
}
}

void MovableText::getRenderOperation(RenderOperation &op)
{
if (this->isVisible())
{
if (mNeedUpdate)
this->_setupGeometry();
if (mUpdateColors)
this->_updateColors();
op = mRenderOp;
}
}

void MovableText::_notifyCurrentCamera(Camera *cam)
{
mpCam = cam;
}

void MovableText::_updateRenderQueue(RenderQueue* queue)
{
if (this->isVisible())
{
if (mNeedUpdate)
this->_setupGeometry();
if (mUpdateColors)
this->_updateColors();

queue->addRenderable(this, mRenderQueueID, OGRE_RENDERABLE_DEFAULT_PRIORITY);
// queue->addRenderable(this, mRenderQueueID, RENDER_QUEUE_SKIES_LATE);
}
}


-Add the files in the Mogre project and follow the instructions to build the project

-If all goes well, you'll get a Mogre.MovableText class in Mogre.dll.

Mwr

23-11-2006 17:54:31

I take it this means that until the next version of Mogre is out that SimpleRenderable can't be extended?

Is there any way of adding a new class to the Mogre source that will extended SimpleRenderable and then let c# classes register eventhandlers with it so that they can extend it. I might of not described what I mean very well here, but I mean some sort of class that is similar to the SimpleRenderableDirector in OgreDotNet.

I'm currently about a third of the way through converting my program from ODN to Mogre and really need to be able to extend SimpleRenderable. I had read that Renderable could be extended already so thought that SimpleRenderable could be too but it seems not.

Bekas

23-11-2006 18:53:53

@Mwr:
Soon I'll start adding code to SVN for extending classes, SimpleRenderable will definately be one of the first. If you want to try it out by compiling the SVN source, I'll let you know when it's in the trunk.

To extend it from C# you'll just subclass it, no extra classes or handlers will be necessary.

GermanDZ

06-06-2007 04:29:59

Hi guys,

I use the code of above, but in Eihort some things have changed, I adapted the code, recompiled MOGRE and WORKS!!!

If somebody needs the updated code (Is not 100% tested yet), I could post it.

pepote

06-06-2007 11:40:29

Can you write a Wiki page talking about the changues?

I think it should be instructive to future updates.

GermanDZ

06-06-2007 14:44:42

Sure,

I have not an account on wiki yet. {I am registering now.}

I will post later when the page is created, please someone make a review/test of the solution.


I cant create an account on WIKI. How can I do that?

Vectrex

07-06-2007 09:47:41

Sure,

I have not an account on wiki yet. {I am registering now.}

I will post later when the page is created, please someone make a review/test of the solution.


I cant create an account on WIKI. How can I do that?


use your normal ogre forums info

GermanDZ

07-06-2007 16:30:00

Done.

You could see the page http://www.ogre3d.org/wiki/index.php/MOGRE_MovableText


See you next time.

Beauty

25-09-2008 00:07:04

Extending Ogre classes is not supported yet, you'll be able to do it with next version of Mogre.

If you can't wait until then, here's what you should do:

-Get Mogre's source code
-Add this file in "include" folder:

Is it now supported or only in 2.x?

Also it would be nice to have add-ons which can be included without recompiling Mogre. Is there a real need to add an add-on like this to Ogre classes? For example MogreBetaGUI can display text without compiling. The informations about SceneNode positins etc. could be read by references.
Or is there a special advantage to compile it into the Mogre library?


Can somebody take a nice screenshot of MovableText?
I would like to add it to the wiki.

Beauty

17-11-2009 16:29:10

MovableText is useful and easy to use.
What a pitty that this extension isn't added to Ogre/Mogre by default.

// create entity
MovableText msg = new MovableText("txt001", "Terminator", "BlueHighway", 4, new ColourValue(200,50,200));
msg.SetTextAlignment(MovableText.HorizontalAlignment.H_CENTER, MovableText.VerticalAlignment.V_ABOVE);
msg.AdditionalHeight = 80.0f

// attach to a SceneNode
node.AttachObject(msg);


More details are here:
http://www.ogre3d.org/wiki/index.php/MOGRE_MovableText

Unfortunately it's needed to recompile Mogre again (with this extension).

Is there an alternative way to add such a functionality to Mogre without recompile?
(I mean an easy to use class, not to code it manually)
I think MogreNewt has something similar inlcuded its code.