OpenGL freetype 创建描边效果及cocos2d-x描边问题

主要参考文章

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在使用后会进行缓存,但通过整体的流程可以看出比位图字体慢许多,不过好处是,在设置字体大小不同的业务需求时,字体不会因为变大而产生模糊的情况。因为原始的文件为矢量字体。

绘制描边的基本方式

网络上查询绘制描边的方式有主要几种

  1. 使用freetype的描边api,会沿着字形极其精确的绘制出满意的描边效果
  2. 八方向绘制多次原始字体
  3. 使用发光模糊效果模拟,也是使用多次绘制的方式,在底下绘制一个模糊的原始字字体,并给其填充颜色

方法2 3都会比较消耗绘制效率,2方法在描边宽度比较大的情况下,穿帮会比较严重,u3d的ngui插件使用的就是其描边方案,3方法在flash上经常使用,不过模糊算法会更加的消耗性能,因为需要大量计算周边像素值,并且有多次渲染。

问题

这里的描边主要是针对TrueType字体,TrueType字体在cocos2d-x的内部处理中使用了freetype库,但是在设置outline的处理上与ferrotype的example2存在着比较大的不同。

他的基本思路是与参考文献1类似,但是在处理原始字形的alpha值时,直接采用了绘制原始字形的bitmap值,另外与描边后的边线进行了居中对齐,最终导致了最终字形与描边位置错误比较严重,也就是比较丑。

另外描边后的偏移位置cocos2d-x也是计算错误的,需要增加两个bbox的x,y偏差值,具体可看参考文献2

updatedupdated2021-01-202021-01-20