Click here to Skip to main content
15,886,774 members
Articles / Programming Languages / C#

Write Text Inside an Image: Add a Poster to Add it in your Mogre Scene

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
19 Feb 2010CPOL 9.9K   5  
To display information in your scene, you can use a billboard represented by the MovableText into (M)ogre but sometimes you just want to put some static text somewhere because it's more readable.

Introduction

To display information in your scene, you can use a billboard represented by the MovableText into (M)ogre but sometimes you just want to put some static text somewhere because it's more readable.

For example:

Create a poster to add it in your Mogre Scene

The Code

Here is the code which uses a lot of my last article.

The steps are as given below:

  1. Create a bitmap with the text in it
  2. Create a texture with this image, then a material
  3. Create a poster (rectangle) and put the texture on it
  4. Return the manualObject created

The part which may interest you is how to get the right size for the created bitmap based on the text...

Also the creation of the manualObject is not necessary but I think it may interest some people to see how to use it.

C#
/// <summary>
/// Creates a 'poster' based on a text.
/// </summary>
/// <param name="Smgr">The scenemanager (necessary to create the manual object).</param>
/// <param name="text">The text to put on the poster.</param>
/// <author>Jonathan ANTOINE</author>
private static ManualObject createALabel(SceneManager Smgr, String text)
{
String textureName = Guid.NewGuid().ToString();
System.Drawing.Font font = new System.Drawing.Font("Calibri", 12, FontStyle.Bold);
Bitmap bitmap = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(bitmap);
 
SizeF measureString = g.MeasureString(text, font);
bitmap = new Bitmap((int)measureString.Width, (int)measureString.Height);
g = Graphics.FromImage(bitmap);
g.FillRectangle(Brushes.Black, 
	new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height));
g.DrawString(text, font, new System.Drawing.SolidBrush(Color.White), new Point(3, 3));
 
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
 
Stream oStream = new MemoryStream();
g.Save();
bitmap.Save(oStream, ImageFormat.Png);
oStream.Flush();
 
//bitmap.Dispose();
//Back to the start of the stream
oStream.Position = 0;
 
//read all the stream
BinaryReader oBinaryReader = new BinaryReader(oStream);
byte[] pBuffer = oBinaryReader.ReadBytes((int)oBinaryReader.BaseStream.Length);
oStream.Close(); //No more needed
TextureManager.Singleton.Remove(textureName); //Remove eventually texture with the same name
unsafe
{
GCHandle handle = GCHandle.Alloc(pBuffer, GCHandleType.Pinned);
byte* pUnsafeByte = (byte*)handle.AddrOfPinnedObject();
void* pUnsafeBuffer = (void*)handle.AddrOfPinnedObject();
 
MemoryDataStream oMemoryStream = new MemoryDataStream(pUnsafeBuffer, (uint)pBuffer.Length);
DataStreamPtr oPtrDataStream = new DataStreamPtr(oMemoryStream);
 
Mogre.Image oMogreImage = new Mogre.Image().Load(oPtrDataStream, "png");
 
TextureManager.Singleton.LoadImageW(textureName, 
	ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, oMogreImage);
 
//handle.Free();
}
String matNam = Guid.NewGuid().ToString();
MaterialPtr _dynamicMaterial = 
MaterialManager.Singleton.Create(matNam, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
Pass pass = _dynamicMaterial.GetTechnique(0).GetPass(0);
 
pass.ShadingMode = ShadeOptions.SO_PHONG;
 
TextureUnitState tus = pass.CreateTextureUnitState(textureName);
tus.SetTextureAddressingMode(TextureUnitState.TextureAddressingMode.TAM_CLAMP);
pass.AddTextureUnitState(tus);
 
_dynamicMaterial.Dispose(); //Dispose the pointer, not the material !
 
ManualObject manualObject = Smgr.CreateManualObject(Guid.NewGuid().ToString());
 
manualObject.EstimateIndexCount(6);
manualObject.EstimateVertexCount(6);
 
manualObject.Begin(matNam, RenderOperation.OperationTypes.OT_TRIANGLE_LIST);
 
//DESSUS
int yWidthVariable = bitmap.Width;
int xWidth = bitmap.Height;
 
manualObject.Position(new Vector3(0, 0, 0));
manualObject.TextureCoord(1, 0);
manualObject.Normal(Vector3.UNIT_Z);
 
manualObject.Position(new Vector3(0, -yWidthVariable, 0));
manualObject.TextureCoord(0, 0f);
manualObject.Normal(Vector3.UNIT_Z);
manualObject.Position(new Vector3(xWidth, 0, 0));
manualObject.TextureCoord(1f, 1);
manualObject.Normal(Vector3.UNIT_Z);
 
manualObject.Position(new Vector3(0, -yWidthVariable, 0));
manualObject.TextureCoord(0f, 0f);
manualObject.Normal(Vector3.UNIT_Z);
manualObject.Position(new Vector3(xWidth, -yWidthVariable, 0));
manualObject.TextureCoord(0f, 1.0f);
manualObject.Normal(Vector3.UNIT_Z);
manualObject.Position(new Vector3(xWidth, 0, 0));
manualObject.TextureCoord(1f, 1.0f);
manualObject.Normal(Vector3.UNIT_Z);
 
manualObject.End();
 
manualObject.CastShadows = false;
 
return manualObject;
}

Also you can get the size of the "poster" by using the boundingbox. An example of use:

C#
manualObject.BoundingBox.Size.x * 0.5f * Vector3.UNIT_Y;

The code can be found as an attached file.

kick it on DotNetKicks.com
This article was originally posted at http://blog.lexique-du-net.com/index.php

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer http://wpf-france.fr
France (Metropolitan) France (Metropolitan)
Jonathan creates software, mostly with C#,WPF and XAML.

He really likes to works on every Natural User Interfaces(NUI : multitouch, touchless, etc...) issues.



He is awarded Microsoft MVP in the "Client Application Development" section since 2011.


You can check out his WPF/C#/NUI/3D blog http://www.jonathanantoine.com.

He is also the creator of the WPF French community web site : http://wpf-france.fr.

Here is some videos of the projects he has already work on :

Comments and Discussions

 
-- There are no messages in this forum --