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:
The Code
Here is the code which uses a lot of my last article.
The steps are as given below:
- Create a bitmap with the text in it
- Create a texture with this image, then a material
- Create a poster (rectangle) and put the texture on it
- 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.
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();
oStream.Position = 0;
BinaryReader oBinaryReader = new BinaryReader(oStream);
byte[] pBuffer = oBinaryReader.ReadBytes((int)oBinaryReader.BaseStream.Length);
oStream.Close();
TextureManager.Singleton.Remove(textureName);
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);
}
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();
ManualObject manualObject = Smgr.CreateManualObject(Guid.NewGuid().ToString());
manualObject.EstimateIndexCount(6);
manualObject.EstimateVertexCount(6);
manualObject.Begin(matNam, RenderOperation.OperationTypes.OT_TRIANGLE_LIST);
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:
manualObject.BoundingBox.Size.x * 0.5f * Vector3.UNIT_Y;
The code can be found as an attached file.
CodeProject