CocosCreator的文本是怎么渲染到网页的
摘要
CocosCreator 的文本组件,输入文字后是怎么将其渲染到网页上面的?阔阔带你从头开始分析!
正文
使用工具
- 谷歌浏览器
- CocosCreator 版本 2.4.7
先说说怎么在网页上显示文字
1.最基本的 html 内文本显示:

浏览器中:

2.然后出现了 canvas 绘制,在 canvas 里显示文字:


你会发现渲染有点模糊,解决办法可以采用增大渲染分辨率,保持 DOM 大小,就清晰了。

3.再后来流行了 WebGL,要想在 WebGL 中显示文本,有一种办法就是先在 canvas 下渲染 2d 的文字,然后将其作为纹理传入 WebGL 进行渲染。CocosCreator 也是这么搞的,这样的方法适合动态生成文字。举个例子(可以 copy 到一个 HTML 里自己跑一下):
|
浏览器中的效果:

CocosCreator 是怎么做的
观察上面的代码,首先文字的大小应该是根据内容进行变化的,而不是像我这样定死一个 200 长度,对于文字大小的测量方法:

打开 CocosCreator 的 v2.4.7 的源码,在 text-utils.js 脚本中有着 safeMeasureText 这个方法,其中就是测量方法,然后还加了缓存,同样的 key 就不用再测了,见下图:

再转到源码中的 letter-font.js 脚本,看下 updateRenderData 这个方法,这个就是装载文字显示数据的方法。在这个方法里执行了 _updateProperties 和 _updateTexture 这两个方法,分别看一看:
先看第一个,对照下面的代码,Label._canvasPool.get() 其实就是 document.createElement("canvas") 的一层封装,获取到了一个 canvas 对象。然后,调用测量方法传入文本获得占据宽高,最后执行 this._texture.initWithElement(this._canvas) 创建了纹理。

再看看 _updateTexture 干了啥:

不难发现,就是对文字的样式、颜色等进行修改,最终调用了 fillText 绘制文字,然后调用了 this._texture.handleLoadedTexture();,再转到源码 CCTexture2D.js 中可以看到这个方法:

在上面这个方法了装入纹理参数,像素格式。
再深入点!!!
看到这里,大概的流程通了,但是 CocosCreator 怎么把文本显示出来的?那些 shader 中的 useProgram 还有 buffer 相关的其他操作呢?
在上面的 handleLoadedTexture 方法中有这样一句代码:
this._texture = new renderer.Texture2D(renderer.device, opts) |
renderer.device 是什么?打开源码目录中 cocos2d/core/renderer/index.js 脚本,其中的 initWebGL 方法就是环境初始化。在 CCGame.js 的 _initRenderer 方法中判断了 canvas 环境还是 webgl 环境!
然后,在 initWebGL 这个方法中有这么一行代码:
this.device = new gfx.Device(canvas, opts) |
挖到 device.js 脚本中看看,在 Device 类的构造函数中也终于找到了我们想要的东西:

然后你会发现 device.js 这个脚本其实就是对 gl 一系列方法的封装,在最后面的 draw 方法中有 shader 的 buffer 操作等一系列方法的封装以及最终绘制方法:

最终调用的绘制方法:

好了,gl 的渲染方法找到了,还差最后一步,它是怎么被调用到的呢?
官方文档有 渲染流 这么一块介绍,渲染流(RenderFlow)是 v2.0 新加的流程,它的作用是可以剔除无用的渲染分支,只进入预先创建好的渲染分支,这样可以有效减少非常多的动态判断。
在 CocosCreator 中的渲染会走到 RenderFlow,在 render-flow.js 中需要渲染的会走入 render 方法!
回过来,在 base-renderer.js 源码中,_draw 正是在设置好一系列 gl 参数后调用了 device 的 draw 方法之中。而 ForwardRenderer 继承自 BaseRenderer,在 render 时就会触发 _draw 方法,将文字渲染出来。
一切豁然开朗!!!
更多文章与分享
个人网站:www.kuokuo666.com
2022!Day Day Up!
CocosCreator的文本是怎么渲染到网页的

