主要参考文章
http://www.cppblog.com/shly/archive/2013/07/14/201796.aspx
http://www.cppblog.com/wc250en007/archive/2011/07/13/150809.html
目的
想了解描边效果的主要原因是因为cocos2d-x自带的效果中(enableGlow,enableOutline,enableShadow),没有一个是满足效果的,enableGlow的效果极其难看,enableOutline的效果感觉Outline的位置总有错误,另外原始3.0版本的描边甚至都存在bug,导致字库的位置是错误的。
基本原理
cocos2d-x的标签类型有三种,位图字体,系统字体,TrueType字体
位图字体与一般的精灵图片类似,从大的精灵表中获取坐标,直接渲染,这个是最快也是最直接的方式
常用的后缀为fnt文件及对应纹理图片
系统字体系统字体为平台相关,比较少用,直接从操作系统已有的字体库中获取字体的位图信息。由于字体文件未必在特定平台都存在,因此此字体几乎没有使用
TrueType字体为矢量字体,这个也是使用频率最高的方式,但是这个效果比较低,因为在使用中,需要根据字体文件,大小,是否描边等参数生成对应的纹理信息,虽然cocos2d-x在使用后会进行缓存,但通过整体的流程可以看出比位图字体慢许多,不过好处是,在设置字体大小不同的业务需求时,字体不会因为变大而产生模糊的情况。因为原始的文件为矢量字体。
绘制描边的基本方式
网络上查询绘制描边的方式有主要几种
- 使用freetype的描边api,会沿着字形极其精确的绘制出满意的描边效果
- 八方向绘制多次原始字体
- 使用发光模糊效果模拟,也是使用多次绘制的方式,在底下绘制一个模糊的原始字字体,并给其填充颜色
方法2 3都会比较消耗绘制效率,2方法在描边宽度比较大的情况下,穿帮会比较严重,u3d的ngui插件使用的就是其描边方案,3方法在flash上经常使用,不过模糊算法会更加的消耗性能,因为需要大量计算周边像素值,并且有多次渲染。
问题
这里的描边主要是针对TrueType字体,TrueType字体在cocos2d-x的内部处理中使用了freetype库,但是在设置outline的处理上与ferrotype的example2存在着比较大的不同。
他的基本思路是与参考文献1类似,但是在处理原始字形的alpha值时,直接采用了绘制原始字形的bitmap值,另外与描边后的边线进行了居中对齐,最终导致了最终字形与描边位置错误比较严重,也就是比较丑。
另外描边后的偏移位置cocos2d-x也是计算错误的,需要增加两个bbox的x,y偏差值,具体可看参考文献2