andyhebear1
04-02-2013 05:24:25
hello! are you want to do write words on texture?
The following code may be what you need!
how to use? like that
The following code may be what you need!
internal void WriteToTexture(string str, ColourValue color) {
string fontname="宋体";
Mogre.FontPtr fontPtr=Mogre.FontManager.Singleton.GetByName(fontname);
Mogre.Box destRectangle = new Box();
destRectangle.bottom = size.Height;
destRectangle.right = size.Width;
WriteToTexture(str, this.texture, size, fontPtr, color);
}
void WriteToTexture(string str, TexturePtr destTexture, Mogre.Box destRectangle, Mogre.FontPtr font, ColourValue color) {
char justify = 'l';
bool wordwrap = true;
WriteToTexture(str, destTexture, destRectangle, font, color, justify, wordwrap);
}
//author: rains
//mail: andyhebear#hotmail.com, andyhebear#gmail.com
// my blog: http://hi.baidu.com/rainssoft
// my web: http://www.masswig.com
unsafe void WriteToTexture(string str, TexturePtr destTexture, Mogre.Box destRectangle, Mogre.FontPtr font, ColourValue color, char justify, bool wordwrap) {
if (destTexture.Height < destRectangle.bottom)
destRectangle.bottom = destTexture.Height;
if (destTexture.Width < destRectangle.right)
destRectangle.right = destTexture.Width;
if (!font.IsLoaded)
font.Load();
//
TexturePtr fontTexture = (TexturePtr)TextureManager.Singleton.GetByName(font.GetMaterial().GetTechnique(0).GetPass(0).GetTextureUnitState(0).TextureName);
HardwarePixelBufferSharedPtr fontBuffer = fontTexture.GetBuffer();
HardwarePixelBufferSharedPtr destBuffer = destTexture.GetBuffer();
PixelBox destPb = destBuffer.Lock(destRectangle, HardwareBuffer.LockOptions.HBL_NORMAL);
// The font texture buffer was created write only...so we cannot read it back :o). One solution is to copy the buffer instead of locking it. (Maybe there is a way to create a font texture which is not write_only ?)
// create a buffer
uint nBuffSize = fontBuffer.SizeInBytes;
uint* buffer = stackalloc uint[(int)nBuffSize /**sizeof(uint)*/];
//uint* buffer = (uint8*)calloc(nBuffSize, sizeof(uint8));
IntPtr ptr_buffer = new IntPtr(buffer);
PixelBox fontPb = new PixelBox(fontBuffer.Width, fontBuffer.Height, fontBuffer.Depth, fontBuffer.Format, ptr_buffer);
fontBuffer.BlitToMemory(fontPb);
//
uint* fontData = (uint*)(fontPb.data);
uint* destData = (uint*)(destPb.data);
uint fontPixelSize = PixelUtil.GetNumElemBytes(fontPb.format);
uint destPixelSize = PixelUtil.GetNumElemBytes(destPb.format);
uint fontRowPitchBytes = fontPb.rowPitch * fontPixelSize;
uint destRowPitchBytes = destPb.rowPitch * destPixelSize;
//
Mogre.Box[] GlyphTexCoords = new Box[str.Length];
Mogre.FloatRect glypheTexRect;
uint charheight = 0;
uint charwidth = 0;
//
for (int i = 0; i < str.Length; i++) {
if ((str != '\t') && (str != '\n') && (str != ' ')) {
glypheTexRect = font.GetGlyphTexCoords(str);
GlyphTexCoords.left = (uint)(glypheTexRect.left * fontTexture.SrcWidth);
GlyphTexCoords.top = (uint)(glypheTexRect.top * fontTexture.SrcHeight);
GlyphTexCoords.right = (uint)(glypheTexRect.right * fontTexture.SrcWidth);
GlyphTexCoords.bottom = (uint)(glypheTexRect.bottom * fontTexture.SrcHeight);
if (GlyphTexCoords.Height > charheight)
charheight = GlyphTexCoords.Height;
if (GlyphTexCoords.Width > charwidth)
charwidth = GlyphTexCoords.Width;
}
}
uint cursorX = 0, cursorY = 0, lineend = destRectangle.Width;
bool carriagreturn = true;
//
for (int strindex = 0; strindex < str.Length; strindex++) {
switch (str[strindex]) {
case ' ': cursorX += charwidth; break;
case '\t': cursorX += charwidth * 3; break;
case '\n': cursorY += charheight; carriagreturn = true; break;
default: {
//wrapping
if ((cursorX + GlyphTexCoords[strindex].Width > lineend) && !carriagreturn) {
cursorY += charheight;
carriagreturn = true;
}
//justify
if (carriagreturn) {
int l = strindex;
uint textwidth = 0;
uint wordwidth = 0;
while ((l < str.Length) && (str[l] != '\n')) {
wordwidth = 0;
switch (str[l]) {
case ' ': wordwidth = charwidth; ++l; break;
case '\t': wordwidth = charwidth * 3; ++l; break;
case '\n': l = str.Length; break;
default:
break;
}
if (wordwrap)
while ((l < str.Length) && (str[l] != ' ') && (str[l] != '\t') && (str[l] != '\n')) {
wordwidth += GlyphTexCoords[l].Width;
++l;
}
else {
wordwidth += GlyphTexCoords[l].Width;
l++;
}
if ((textwidth + wordwidth) <= destRectangle.Width)
textwidth += (wordwidth);
else
break;
}
if ((textwidth == 0) && (wordwidth > destRectangle.Width))
textwidth = destRectangle.Width;
switch (justify) {
case 'c': cursorX = (destRectangle.Width - textwidth) / 2;
lineend = destRectangle.Width - cursorX;
break;
case 'r': cursorX = (destRectangle.Width - textwidth);
lineend = destRectangle.Width;
break;
default: cursorX = 0;
lineend = textwidth;
break;
}
carriagreturn = false;
}
//abort - net enough space to draw
if ((cursorY + charheight) > destRectangle.Height)
goto stop;
//draw pixel by pixel
for (uint i = 0; i < GlyphTexCoords[strindex].Height; i++)
for (uint j = 0; j < GlyphTexCoords[strindex].Width; j++) {
float alpha = color.a * (fontData[(i + GlyphTexCoords[strindex].top) * fontRowPitchBytes + (j + GlyphTexCoords[strindex].left) * fontPixelSize + 1] / 255.0f);
float invalpha = 1.0f - alpha;
uint offset = (i + cursorY) * destRowPitchBytes + (j + cursorX) * destPixelSize;
ColourValue pix;
PixelUtil.UnpackColour(&pix, destPb.format, &destData[offset]);
pix = (pix * invalpha) + (color * alpha);
PixelUtil.PackColour(pix, destPb.format, &destData[offset]);
}
cursorX += GlyphTexCoords[strindex].Width;
}//default
break;
}//switch
}//for
stop:
GlyphTexCoords = null;
destBuffer.Unlock();
// Free the memory allocated for the buffer
free(buffer);
buffer = null;
}
private unsafe void free(uint* buffer) {
//buffer = null;
}
private unsafe IntPtr calloc(uint nBuffSize, int p,out GCHandle gcHandle) {
gcHandle = GCHandle.Alloc(new byte[nBuffSize * p], GCHandleType.Pinned);
IntPtr bufferPtr = gcHandle.AddrOfPinnedObject();
return bufferPtr;
}
how to use? like that
internal void WriteToTexture(string str, ColourValue color) {
string fontname="you font";
Mogre.FontPtr fontPtr=Mogre.FontManager.Singleton.GetByName(fontname);
Mogre.Box destRectangle = new Box();
destRectangle.bottom = 100;
destRectangle.right = 32;
WriteToTexture(str, this.texture, size, fontPtr, color);
}