mygui与hge结合

mygui中使用gdi字体

egamesir posted @ 2011年10月21日 13:12 in gui with tags font gdi gui hge mygui , 3439 阅读

现在很多网络游戏里都使用了FreeType来显示中文字体,它可以实现很绚丽的字体效果。但是有个缺点就是加载太慢了。尤其是mygui里使用FreeType慢的让我无法接受,故打算将其字体支持增加gdi字体,以便备用吧。

程序参考了微妙的平衡(这小子最近消失了)早期的代码,hge的gdi字体。其实这种方法不光是能用于mygui,几乎dx平台下面都能用。这方面的资料也挺多的了,主要是利用一个api,GetGlyphOutline。大致说一下,该函数取得被选进指定设备环境的TrueType字体的字符轮廓或位图。这个函数的具体说明不在此粘贴,可以自己Google。
 
贴一张图(来自网络)来帮助理解字符轮廓:
 
 
 
得到字符轮廓以后,我们把它渲染到一张存在于显存上的texture上,并保存字符对应的位置信息,在用到的时候就可以通过查找的方式将其渲染出来了。为了效率考虑,字符在第一次使用的时候去加载并保存到一张大的texture上,从左到右从上到下码上去。这样做的好处是,减少渲染批次,提高渲染效率。
 
1.增加ResourceGdiFont类,基本的先从ResourceTrueTypeFont类改过来就可以了,主要是解析一些配置文件里的信息。
 
2.该类中增加loadCharactor函数,用来第一次加载字符。从GetGlyphOutline获取到字符轮廓,锁定texture,将字符轮廓信息拷贝到texture的指定位置上,然后保存位置信息。
 
3.初始化函数中。创建并设置DC,根据配置创建gdi字体,CreateFont。然后创建texture用来保存字符信息。
 
4.在MyGUI_FontManager中注册字体类型。FactoryManager::getInstance().registerFactory<ResourceGdiFont>(XML_TYPE_RESOURCE)。同样还有销毁的地方,按照TrueTypeFont的样子抄过来就行了。
 
5.修改字体配置文件MyGUI_Media/MyGUI_Fonts.xml。直接改成下面这样就不需要改其他文件,可以测试了。
 
<?xml version="1.0" encoding="UTF-8"?>
  <MyGUI type="Resource" version="1.1">
    <Resource type="ResourceGdiFont" name="DejaVuSansFont.17">
    <Property key="Source" value="宋体"/>
    <Property key="Size" value="19"/>
    <Property key="Resolution" value="50"/>
    <Property key="Antialias" value="false"/>
    <Property key="SpaceWidth" value="4"/>
    <Property key="TabWidth" value="8"/>
    <Property key="CursorWidth" value="2"/>
    <Property key="Distance" value="6"/>
    <Property key="OffsetHeight" value="0"/>
  </Resource>
</MyGUI>

6.这样启动程序的时候就可以显示宋体字了。
 
7.注意代码中默认的字符texture大小是128*128,英文和符号勉强够用,到时候出错了,记得增加texture的大小。
 
8.总结:还有几点需要注意。GetGlyphOutline的几个参数的意义及使用;texture上字符的位置信息;拷贝字符信息时需注意;本程序对mygui的L8A8像素格式暂不支持,只支持R8G8B8A8 32位像素格式。
 
9.详细看代码吧(没有提供可运行的demo程序,自己将这两个文件加到mygui里稍加改动就可以看到效果了)。
 
 

PS: 2011.9.22 这几天发现使用我之前写的 mygui与hge的结合 的hge渲染mygui版本,字体有个问题。有一部分字,尤其是开始的时候没有加载的字符,后面都显示不出来。苦苦查找了好几天,最后发现原来是Texture_Lock的一个参数问题。注意红色部分。道理自然也明了了。
void* HGETexture::lock(TextureUsage _access)
{
    if (mLock)
        return nullptr;
    DWORD* lockbits = mpHGE->Texture_Lock( mpTexture, TextureUsage::Write!=_access );
    mLock = true;
    return (void*)lockbits;
}
 

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter