i recently found that current implementation of GUI font can not use antialiased fonts (= font with transparency and halftones) at all, downgrading such fonts to simple black`n`white pattern at load time (with awful results). After some search i realized that is it by design: anyone who want it should find third-party implementation for bitmap fonts. but this is not really necessary, because IGUIFont already have all infrastructure for that task. there is even no need in patching Irrlicht sources!
But i would ask somebody who can patch sources in SVN to add small flag that will allow to use such fonts internally. see function comments for details
Here is the function that properly loads antialiased font:
Code: Select all
/*
Current implementation of CGUIFont (irr1.1) is not
able to use alphablended or antializased fonts.
This is because of the following lines in the
readPositions32bit() function
...
else
if (*p == colorBackGround)
*p = colorBackGroundWithAlphaFalse;
else
*p = colorFont;
...
All pixels are replaced with font color or font background, no choice :(
there is a hack that can fix the situation:
- we asking textture BEFORE IGUIFont and coping all bits into separate memory
- after IGUIFont corrupts texture, we replacing it back with original bits. This is possible because we can get the same texture by using the same path (look into Irrlicht internal texture manager)
- after that IGUIFont will use antialiased texture with proper character positions*/
Code: Select all
IGUIFont* AntialiasedFontFixer(IrrlichtDevice *device, const char* szTexturePath)
{
ITexture* originalTexture=device->getVideoDriver()->getTexture(szTexturePath);
ECOLOR_FORMAT iSrcFormat=originalTexture->getColorFormat();
if(iSrcFormat!=ECF_A8R8G8B8){
// Sorry, only 32bit textures at this time...
return device->getGUIEnvironment()->getFont(szTexturePath);
}
core::dimension2d<s32> size=originalTexture->getOriginalSize();
s32 iTexSize=size.Width*size.Height*4;/*4 is the size of ECF_A8R8G8B8 pixel */
BYTE* SrcData=(BYTE*)originalTexture->lock();
BYTE* SrcDataCopy=new BYTE[iTexSize];
memcpy(SrcDataCopy,SrcData,iTexSize);
originalTexture->unlock();
IGUIFont* fontOut=device->getGUIEnvironment()->getFont(szTexturePath);
// Now we have to overwrite the same texture (corrupted by IGUIFont) again with original bitmap data
DWORD dw1=((DWORD*)SrcDataCopy)[0];
DWORD dw2=((DWORD*)SrcDataCopy)[1];
DWORD dw3=((DWORD*)SrcDataCopy)[2];
for(int i=0;i<size.Width*size.Height;i++){
if((((DWORD*)SrcDataCopy)[i])==dw1 || (((DWORD*)SrcDataCopy)[i])==dw2){
(((DWORD*)SrcDataCopy)[i])=dw3;
}
}
BYTE* SrcDataAgain=(BYTE*)originalTexture->lock();
memcpy(SrcDataAgain,SrcDataCopy,iTexSize);
originalTexture->unlock();
delete[] SrcDataCopy;
return fontOut;
}
replace device->getGUIEnvironment()->getFont(szTexturePath);
with AntialiasedFontFixer(szTexturePath); in your code
that is all!