讨论cocos2d-x字体绘制原理和应用方案
转自:http://blog.csdn.net/langresser_king/article/details/9012789
个人一直认为,文字绘制是cocos2d-x最薄弱的环节。对于愤怒的小鸟之类的游戏,cocos2d提供的文字绘制功能已足够使用。但是对于一个mmo来说,则完全不够。一个优秀的mmo客户端必然会对其有进行优化和再封装的操作。
cocos2d-x支持两种文字绘制方式(均支持中英文),一种是CCLabelTTF,一种是CCLabelBmpFont。
CCLabelTTF原理是调用系统api绘制字形纹理到一张CCImage上面,然后将其作为CCSprite进行渲染。好处是支持系统绘制文字不需要附加字体文件(当然,如果有需要也可以使用自定义字体文件,但是本质还是系统api进行文字绘制。),文字排版和渲染效果相对较好(尤其是ios这种以文字渲染见长的系统)。 缺点是绘制文字速度慢,只要是文字绘制就会生成一张贴图,没有缓存机制。 没有提供获取字形矩阵的接口,上层无法进行再次排版(这就意味着上层无法做缓存机制,另外富文本渲染的时候也需要这种接口,否则就需要以牺牲效率为代价了)。
CCLabelBmpFont原理是通过字形生成工具预先生成一个字体文件(fnt的字体配置和png的字形纹理),好处是速度快,不耗内存。缺点是支持文字数目有限,所以只支持固定文字的渲染,如控件文字、物品名称等,如果是玩家姓名、聊天栏这类输入内容不定的,还是需要使用CCLabelTTF。
文字渲染后续值得优化的有两个方向:
1、直接使用freetype,然后就是正常的游戏引擎的文字处理方式,支持缓存,速度快,描边之类的效果也可以内嵌
2、从底层获取字形矩阵的接口,然后上层字行排版,这个可以兼容现有的代码,而且排版难度比我们想象中要低很多。
总结下,游戏固有内容的文字渲染推荐使用CCLabelBmpFont,输入内容不定的,选用CCLabelTTF
CCLabelBmpFont只支持一张png字形纹理图片(BatchNode绘制时需要保证贴图在一样纹理上面),但是很多bitmap font生成工具会生成多张png图片资源。我写了个python脚本用于合并多个png字形资源。
- import re, Image;
- def create(font):
- fp = open(font+".fnt", "r");
- data = [];
- files = [];
- for line in fp:
- if line.find("pages=2") != -1:
- line = line.replace("pages=2", "pages=1");
- elif line.find("file=") != -1:
- match = re.search("file=\"(?P<file>.+)\"", line);
- if match:
- files.append(match.group("file"));
- if line.find("id=0") == -1:
- continue;
- line = re.sub("file=\".+\"", "file=\"{0}\"".format(font +"_1.png"), line)
- elif line.find("page=1") != -1:
- match = re.search("y=(?P<y>[0-9]+)", line);
- y = int(match.group("y"));
- y += 512;
- line = re.sub("y=[0-9]+", "y={0}".format(y), line);
- data.append(line);
- fp = open(font + "_1.fnt", "w");
- fp.writelines(data);
- fp.close();
- height = 0;
- merge = Image.new("RGBA", (512, len(files) * 512), 0);
- for file in files:
- img1 = Image.open(file);
- merge.paste(img1, (0, height));
- height += img1.size[1];
- merge.save(font + "_1.png", quality=70);
- create("name_outline");
讨论cocos2d-x字体绘制原理和应用方案的更多相关文章
- Android View绘制原理分析
推荐两篇分析view绘制原理比较好的文章,感谢作者的分享. <Android应用层View绘制流程与源码分析> <View 绘制流程>
- UIView的绘制原理
当UIView调用setNeedDisplay之后, 系统会调用view对应layer的 setNeedsDisplay, 在当前runloop即将结束的时候调用CALayer的display方法. ...
- Android面试收集录12 View测量、布局及绘制原理
一.View绘制的流程框架 View的绘制是从上往下一层层迭代下来的.DecorView-->ViewGroup(--->ViewGroup)-->View ,按照这个流程从上往下, ...
- OpenGL字体绘制
/* glfont.hpp sdragonx 2019-08-15 00:03:33 opengl字体类,提供初学者参考学习 opengl初始化之后,创建字体 font.init(L"微软雅 ...
- UIView绘制原理,异步绘制
绘制原理 首先看一幅流程图 UIView调用setNeedsDisplay方法后,实际上并没有发生当前视图的绘制工作,而是在之后的某一时机进行绘制工作,为什么会在之后的某一时机进行绘制工作呢? 当UI ...
- Android-图像原理/绘制原理
图像原理 先专门讲解图片,一想到图片有那些特点: 宽/高 格式jpg/jpeg/... 大小43.kb/... 图片是由像素点组成:像素点是正方形的,只是像素点很小很多,看起来可以拼接圆形⭕️, ...
- GR32 TImage32的图层绘制原理
转载:http://blog.sina.com.cn/s/blog_491aced20100ded4.html TImage32的继承顺序如下:TCustomControl->TCustomPa ...
- view的绘制原理
转:http://blog.csdn.net/berber78/article/details/42069301 自定义UI控件,需继承 View类或View的子类,并重载View类中的一些方法,不必 ...
- android自定义View的绘制原理
每天我们都会使用很多的应用程序,尽管他们有不同的约定,但大多数应用的设计是非常相似的.这就是为什么许多客户要求使用一些其他应用程序没有的设计,使得应用程序显得独特和不同. 如果功能布局要求非常定制化, ...
随机推荐
- T-sql isnull函数介绍
今天在给同事调取数据的时候,同事反馈说数据偏少,我仔细检查,发现sql语句条件都正确,逻辑没哪里不对,最后经过仔细排查,才发现问题出在null字段上 表中有一列是允许为null值,比如查询名字不为测试 ...
- angularJS 使用自定义指令输出模板
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...
- C# OO(初级思想)
继承,多态,封装 在C#中,为了能够合理描述自然界的规律,面向对象的编程引入了继承的概念,是面向对象编程中最重要的概念之一,定义了如何根据现有的类创建新类的过程. 继承:一个类派生出来的子类具有这个类 ...
- ASP.NET CORE 2.1无法添加控制器、视图
常规操作:右键Controllers,添加控制器 结果提示:运行所选代码生成器时出错 在控制器里快速添加视图也得到同样的错误提示 既然提示代码生成器了,对比了一下2.0和2.1的代码,发现2.1默认没 ...
- 纯div+css制作的弹出菜单
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 记一次kafka客户端NOT_COORDINATOR_FOR_GROUP处理过程
转发请注明原创地址:https://www.cnblogs.com/dongxiao-yang/p/10602799.html 某日晚高峰忽然集群某个大流量业务收到lag报警,查看客户端日志发现reb ...
- Form.ShowWithoutActivation 属性
获取一个值,该值指示显示窗口时是否激活它. 命名空间: System.Windows.Forms程序集: System.Windows.Forms(在 System.Windows.Forms.d ...
- JavaSE中日期处理
一.java中日期类之间的关系: 其中: 1):java.sql.Date.java.sql.Time和java.sql.Timestamp这三个类是专门和数据库打交道的,它们都是java.util. ...
- ArrayList 和 HashMap 的默认大小是多数?
ArrayList 和 HashMap 的默认大小是多数? 在 Java 7 中,ArrayList 的默认大小是 10 个元素,HashMap 的默认大小是16个元素(必须是2的幂).这就是 Jav ...
- FormatUtil类型格式转换
package cn.edu.hbcf.common.utils; import java.math.BigDecimal; import java.math.BigInteger; import j ...