Todo on this page:
  • add screenshot
  • add related version number


Features:

  • The text is attached to a {LEX()}SceneNode{LEX} and therefore follows its movements and gets smaller when further away
  • The text is always facing the camera
  • The text can be positioned horizontally and vertically (center, left, etc...)
  • The text can be translated on the UNIT_Y vector
  • Similar to MOGRE MovableText
  • Works without compiling Mogre


Author: smiley80
Info Forum thread: here

Table of contents

Usage

MovableText mt = new MovableText("helloWorld", sceneMgr, sceneNode, new Size(128, 32));
mt.SetText("Hello World!", new System.Drawing.Font(FontFamily.GenericSansSerif, 16, 
           FontStyle.Regular, GraphicsUnit.Pixel), Color.Red);

Source code

Usable with Mogre versions: ??

namespace Test
{

using System;
using System.Drawing;
using System.Runtime.InteropServices;

using Mogre;

public sealed class MovableText : IDisposable
{
    private Billboard billboard;
    private BillboardSet billboardSet;
    private MaterialPtr material;
    private SceneManager sceneMgr;
    private Size size;
    private TexturePtr texture;

    public MovableText(string name, SceneManager sceneMgr, SceneNode node, Size size)
    {
        this.texture = TextureManager.Singleton.CreateManual(
            name + "Texture",
            ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME,
            TextureType.TEX_TYPE_2D,
            (uint)size.Width,
            (uint)size.Height,
            0,
            PixelFormat.PF_A8R8G8B8);

        this.material = MaterialManager.Singleton.Create(name + "Material", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
        this.material.GetTechnique(0).GetPass(0).CreateTextureUnitState(this.texture.Name);
        this.material.SetSceneBlending(SceneBlendType.SBT_TRANSPARENT_ALPHA);
        this.material.SetDepthCheckEnabled(false);

        this.billboardSet = sceneMgr.CreateBillboardSet();
        this.billboardSet.SetMaterialName(this.material.Name);
        this.billboardSet.RenderQueueGroup = (byte)RenderQueueGroupID.RENDER_QUEUE_OVERLAY;

        this.billboard = this.billboardSet.CreateBillboard(Vector3.ZERO);
        this.billboard.SetDimensions(size.Width, size.Height);
        this.billboard.Colour = ColourValue.ZERO;

        node.AttachObject(this.billboardSet);
        this.sceneMgr = sceneMgr;
        this.size = size;
    }

    public Vector3 Offset
    {
        get
        {
            return this.billboard.Position;
        }

        set
        {
            this.billboard.Position = value;
        }
    }

    public bool Visible
    {
        get
        {
            return this.billboardSet.Visible;
        }

        set
        {
            this.billboardSet.Visible = value;
        }
    }

    public void Dispose()
    {
        this.billboardSet.DetachFromParent();
        this.sceneMgr.DestroyBillboardSet(this.billboardSet);
        this.billboardSet.Dispose();
        this.billboardSet = null;
        this.sceneMgr = null;

        this.material.Unload();
        MaterialManager.Singleton.Remove(this.material.Handle);
        this.material.Dispose();
        this.material = null;

        this.texture.Unload();
        TextureManager.Singleton.Remove(this.texture.Handle);
        this.texture.Dispose();
        this.texture = null;

        GC.SuppressFinalize(this);
    }

    public void SetText(string text, System.Drawing.Font font, Color colour)
    {
        using (Bitmap bitmap = new Bitmap(this.size.Width, this.size.Height))
        {
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                using (SolidBrush brush = new SolidBrush(colour))
                {
                    g.Clear(Color.Transparent);
                    g.DrawString(text, font, brush, PointF.Empty);
                    ConvertImageToTexture(bitmap, this.texture.Name, this.size);
                }
            }
        }
    }
   
    private static unsafe void ConvertImageToTexture(Bitmap image, string textureName, Size size)
    {
        int width = size.Width;
        int height = size.Height;
        using (ResourcePtr rpt = TextureManager.Singleton.GetByName(textureName))
        {
            using (TexturePtr texture = rpt)
            {
                HardwarePixelBufferSharedPtr texBuffer = texture.GetBuffer();
                texBuffer.Lock(HardwareBuffer.LockOptions.HBL_DISCARD);
                PixelBox pb = texBuffer.CurrentLock;

                System.Drawing.Imaging.BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                CopyMemory(pb.data, data.Scan0, (uint)(width * height * 4));
                image.UnlockBits(data);

                texBuffer.Unlock();
                texBuffer.Dispose();
            }
        }
    }

    [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
    private static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length);
}

}

See Also
see_also.jpg