我所熟悉的2D图形框架
1. Qt graphics-view框架
研究生期间基于该框架开发了IMMComposer可视化创作软件,见识了qt这个2D图形框架:清晰的坐标层次系统(设备视图坐标系、场景坐标系、图元局部坐标系),底层采用bsp树管理场景,QT demo中自带的示例轻松处理4000+个item的绘制,交互(hover和click等事件),该框架有个问题不支持批量绘制:每个item都单独调用draw函数完成绘制。
2. Quick2 Scene Graph
QT5.0引入,最大亮点基于OpenGL2.0和OpenGLES2.0,支持shader。scene graph不仅适合2d图形,还能够管理3D图形。场景图更加适合复杂的图形场景,大图形包含很多小图形、子图形,层次感比较明显的场景。例如场景中有很多坦克,每个坦克有炮筒、坦克藏、底座、链条等字图形。场景图层次树的建立能够加速剔除(culling),碰撞检测的速度。OSG中场景图的使用更加玲离尽致。
官方文档谈及该框架亮点:批量绘制,减少状态改变,减少draw call,尽可能地挖掘硬件特性。
官方的这个说法谈谈自己的想法:2D图形材质主要是纹理和颜色,例如场景中包含大量各不相同的icon,和颜色各异的图形,以及一段文字。颜色各异的图形顶点指定颜色,采用统一的绘制模式(GL_TRIANGLES)很容易做到批处理。但是纹理各异的icon,以及一段文字如何做批处理呢?只有一种做法:纹理合并,icon和文字的纹理都是小矩形,将这些小矩形拼凑成若干个大的纹理,然后通过纹理坐标索引纹理内不同区域,从而达到批处理效果。
qt quick2支持FBO/ 软件方法绘制图形,软件方法和fbo方法绘制图形都需要两个步骤:1)先将图形画到一个buffer上,fbo方式画到显存的buffer上,软件方法画到内存的buffer;2)将buffer以贴纹理的方式绘制到屏幕上。
3. ScaleForm
在2011年siggraph中发现了这个图形引擎。能越狱youtube上有一个讲座视频。
4. 最近一直捉琢磨着写一个通用的2D渲染引擎,底层用opengl绘制,主打批量绘制和场景树,草稿如下:
2D 图形引擎构思
BatchRender 和 SceneGraph 分离。
SG管理场景中所有Item。
BatchRender每次遍历SG中所有item,拷贝顶点、材质、纹理,然后归类打包批量上传给OpenGL。
为毛场景树?
+ 快速剔除屏幕之外的item
+ 快速鼠标拾取,甚至hover 效果!
场景树瓶颈何在?
+ Item的增加、删除、遍历
采用KDTree QuadTree
后者简单点
为毛批量绘制?
+ 减少CPU中断,GPU等待机率,提升帧率
GraphicsItem 属性
+ geometry description: vertices list
用于绘制
+ colors: RGBA
材质
+ textureId: texture
纹理
+ boundingBox
用于交互 拾取 相交
+ isDirty
表征是否脏,BatchRender访问过将其置为false
+ forceSingleRender
该item 强制单独绘制,颜色设置glColor4f,纹理单独绑定,顶点单独上传。
动画控制模块,根据算法 修改GraphicsItem的几何、材质信息。
Item顶点过多,做alpha渐变可以直接使用归类Color4f。
Why COCOS2D-X
目前手游很火,前几天跟几个朋友聊天,他们计划业余时间搞个游戏出来,正好我也琢磨着写个2D的东西出来,不谋而合,我理所当然负责客户端。。
既然一起搞游戏,一切自己写不现实,不比在公司上班(我们组的引擎基本上不依赖第三方库,90%是自己写),基于一个热门、成熟的开源库开发比较靠谱点。
接触3D、OpenGL 七八个年头了,常见算法都接触过,2D的东西难度不大,关键在UI以及具体业务逻辑的复杂性。最近手游很火cocos2d很火,最近决定选择cocos2D图形引擎,额外还有两个原因:
1. 它基于OpenGL开发,2D部分对我没有任何难度,纹理 / 纹理打包,批处理技术,场景管理,FBO,这些非常之熟悉。
2. Android上使用cocos2d,通过JNI接口与Java层交互,我入职一年多主要从事android ndk开发,负责引擎部分模块,最近刚刚转向上层Java开发。
引用
3. Game engines: what are scene graphs?