Write word on texture fast! use mogre!

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!


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);
}

andyhebear1

19-02-2013 05:04:21

how load you font,look:
viewtopic.php?f=8&t=11839