我个人认为CEGUI在字体渲染上走了一条貌似优雅,但实际却被证明是错误的道路。(至少我是这么觉得,我的试验也是这么证明着。也许这种想法有错,真的有错,找到再改。)
首先说说CEGUI处理文字渲染的基本流程。
1. Font::getGlyphData
这里需要一个utf32的codepoint,返回的是一个FontGlyph(糅合了codepoint和Image的Map)
2. FreeTypeFont::rasterise
这里对一个指定的codepoint范围内文字进行渲染出Imageset里的Image(每个文字一个Image)
就这样吧,是不是很简单。再说点其他的。
1. Font::drawText
绘制字符串到GeometryBuffer里,这里要对一个个文字进行排版,用FontGlyph里的Image进行绘制。因此,在这里可以控制文字的显示状态。(比如颜色,间距等,其实一些文字效果也可以在这里实现,比如描边,阴影,粗体,斜体,下划线等)
2. FreeTypeFont::drawGlyphToBuffer
CEGUI支持位图字体和矢量字体(FT)两种格式,其实都一样(都是用Image配一个codepoint索引,当然也可以自己手动设置一个指定字体的Image)。最常用的还是FreeType加载矢量字体,否则工作量也是个问题。通过FT把指定文字渲染到一个bitmap,然后用RGBA 像素格式拷贝到一块内存缓冲。从此生成一张Imageset,然后在其上定义各个Image(文字)。(CEGUI默认GLYPHS_PER_PAGE为256)
但是这种文字生成方式是有问题的,首先对于字符有限的语言(如英文)没这个必要(一次加载就可以了)。其次,对于字符数量庞大的语言(如中文)也没必要(因为CEGUI是指定范围渲染的,就是说他会根据要显示的codepoint进行前前后后生成一堆垃圾文字)。貌似优雅,却不怎么实用。其次,CEGUI的文字统一实用RGBA像素格式,也就是说每像素4Byte。是不是换成LA(2Byte)格式要好些?通过对搜狐天龙2的渲染流程使用PIX查看,可以得知搜狐已经改成了2B的LA像素格式(D3DFMT_A8L8)。所以,这么一来要做的工作也渐渐清晰了。
1. 去除废字的生成(这个毫无疑问)
2. 支持要显示文字的预生成(解决瞬间显示大量文字时卡帧问题)
3. 支持生成文字的动态释放(清理不常用的文字,节约资源)
4. 文字图片像素格式使用2Byte的LA格式(能省则省)
5. 从字体定义的XML文件读取配置(避免硬编码)
文字管理提供两种实现方式:
1. 手动管理(提供文字准备和释放接口,在需要的时候手动进行文字的加载和释放)
2. 系统管理(只需对文字使用情况做好配置,系统对文字加载和释放进行动态管理)