Skip to main content

History: MOGRE MovableText by Billboards

Source of version: 9 (current)

Copy to clipboard
            {TRANSCLUDE(page="todobox")}* add screenshot
* add related version number{TRANSCLUDE}

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: ((User:Smiley80|smiley80))
%info% Forum thread: [http://www.ogre3d.org/addonforums/viewtopic.php?p=71507#p71507|here]

{maketoc}

!!Usage
{CODE(wrap="1", colors="c#")}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);{CODE}

!!Source code
Usable with Mogre versions: __??__
{CODE(wrap="1", colors="c#")}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);
}

}{CODE}

{TRANSCLUDE(page="seebox")}* ((MOGRE MovableText)) | ((MovableText))
* ((MovableTextOverlay)) - similar, but only for text
* ((Simple text in MOGRE)) - shows text independent of a {LEX()}SceneNode{LEX}
* ((Easy Debug Text for MOGRE)) - shows a text, which can be updated
* ((SpriteManager2d)) | ((MOGRE SpriteManager2d)) - code snippet
* ((OgreSprites)) - similar, but without use of ''Billboard''
* ((ManualObject 2D))
* {LEX()}Overlay{LEX}
* {LEX()}Billboard{LEX}
* {LEX()}GUI{LEX} - several gui systems{TRANSCLUDE}