引擎设计跟踪(九.14.2i) Android GLES 3.0 完善
最近把渲染设备对应的GLES的API填上了. 主要有IRenderDevice/IShader/ITexture/IGraphicsResourceManager/IIndexBuffer/IVertexBuffer.
都是体力活, 根据文档(https://www.khronos.org/opengles/sdk/docs/man3/)填上对应的API就可了.
遇到的问题纪录在下面:
- Stick to the standard
- C++standard并没有要求char必须是unsigned
typedef char uint8; 发现这个在gcc上 uint8是带符号的, 于是改为 typedef usigned char uint8; - 使用标准库函数. MSVC上有abs(float) 函数, 在android上跑的时候发现数学计算有问题, 最后追到这个函数
原来gcc没有abs(float), 查了下标准 (http://www.cplusplus.com/reference/cstdlib/abs/?kw=abs), 标准确实没有, 只有fabs(). gcc下会自动匹配abs(int), 因为没开警告, 所以没发现.
- C++standard并没有要求char必须是unsigned
- Vertex Shader 编译错误:
- Error: uniform variables in vertex shader do not fit in 256 vectors.
GLES3.0的vertex shader uniform最少也是256. 这个很奇怪. 因为blade的骨骼动画是按照VS3.0的最低要求(256 registers)来写的, shader里面float2x4[120] 用了240个寄存器, 还有2个matrix44, 是8个寄存器.总数248应该没有超. 目前暂时把骨骼数量改为110. - 另外DQ动画上, HLSL的float2x4在转成GLSL时, hlsl2glsl 对其做了转置, 所以是float4x2, 这样就用掉了4个寄存器. 解决方法是直接用float4数组, 这样在D3D和GLES上都适用.
- Error: uniform variables in vertex shader do not fit in 256 vectors.
- GLES 的适配:
GL的sampler属性默认是绑定在贴图上的. (glTexParameter), 这个跟D3D9的sampler state 有所不同, 幸好GLES3.0有sampler object glGenSamplers/glBindSampler/glSamplerParameter 可以实现和d3d一样的设置方式.
整体上GLES.30没有遇到大的问题, 主要是因为去年工作上的积累, 所以实现起来比较快.
目前blade的地形和DQ动画都可以跑在android真机上了, 关于这两个模块, 动画没有做任何适配, 除了某些设备上的bug的特殊workaround.
简单记录一下地形的问题:
- 压缩贴图不能更新部分区域, 或者部分更新有限制( glCompressedTexSubImage ), 而d3d上可以直接lock压缩贴图来更新局部区域. 这样在composite altas的时候会报错. 解决方法不难, 用Image接口(soft buffer)先合并好, 最后一次性上传, 这个方式对于GL/ES和D3D都适用. 而android上的runtime没有编辑模式, 所以不会有动态更新.
- 在测试的android设备上地形的批次合并变慢, 估计额外的带宽太大. 所以在android上把批次合并关了. 这个只需要改配置文件, 因为批次合并本来在windows上就是可以运行时配置, 并保存到配置文件的.
- android上的地形纹理从 512x512改成256x256, 对于一个4x4的atlas, windows上贴图大小是2048x2048, android上是1024x1024. 给BladeTexCompressor加上了scale参数, 同时给地形模块添加了额外的配置参数:texture size, 以便于动态适配.
- 另外为了效率, 地形的detail normal也暂时关了, 因为detail normal用的是atlas normal map, 会多4次采样.
其他一些更新:
- 加入了arm的NEON SIMD,这个是拿的DirectXMath的代码, 之前做SSE的时候已经加入了, 但是没打开NEON, 这次把它调通, 做一些修改和适配.
- 加入了message box. 因为message box是IPlatformManager的feature, 在windows上直接调用API, android上需要JNI调用java来适配. 需要注意的是这个java文件也是放在platform level, 跟具体的project无关, 只需要最终build apk的时候复制到java的src下面.
- shader precompile: 这个之前提到过, 在app level加上一个event handler, 加载包内的所有shader, 并保存为binary格式, 存储到本地文件夹, 并将"shader:/"路径切换为本地路径. 要注意很多细节.比如比如编译shader需要在GLES初始化以后才能做, 这个幸好blade有一个render device ready的事件. 遇到的问题是所有shader的预加载也是处理的这个事件, 而shader加载必须要在shader-precompiling结束后才能正确执行. 所以这两个handler有顺序冲突.这个问题可以抽象为event handler的调用顺序问题, 因为handler在内部存储/调用的顺序是不确定的, 导致同一个event的多个handler的调用顺序是undefined. 记得工作的时候, 第一个项目也遇到类似的问题, 当时是根据注册的顺序来调用. 但是现在觉得, 这样相当于两个不想干的模块有了注册顺序上的弱耦合, 而且注册顺序难以控制, 不是很好. 现在的做法是加了优先级, 同一个优先级的handler调用顺序不确定, 但是优先级不同的, 调用是有顺序的.因为顺序碰撞的情况比较少, 所以用几个优先级就可以了.将shader pre-complie设置为最高优先级, 这样就可以在GLES初始化以后第一时间编译shader, 具体如何判断shader是否需要重编译也有点繁琐, 需要对比文件个数, 时间戳等等, 这里就不纪录了.
目前在Adreno 330 上的release build, 一个512x512的地形, 可以跑30-50FPS, 某些设备是30, 某些是50. 具体还没有时间去profille, 猜测效率瓶颈可能有两个, 一个是顶点/三角形数量, 另一个是atlas是在fragment shader里面要动态计算uv, 并且需要多次纹理采样.
个人觉得如果架构本身支持多平台抽象, 那么平台移植的工作量不大, 主要工作量应该是在优化上. 一个真正可用的引擎不仅仅是能跑起来就可以了.
下面贴一个地形demo的apk和obb吧, 可以在真机上运行, 需要GLES3.0的支持, 只是简单刷了一个地形, 没有仔细去编辑:
最近android的进度主要得益于工作上android的积累, 另外设计上一直以跨平台为目标, 所以改动不是很大.
突然有想做indie game的冲动, 甚至有了一些移动端小型3D动作游戏的idea, 可惜现在积累还不够. 后面如果有机会的话再做indiegame吧. 而且现在有了孩子, 考虑的因素也多了. 后面会放慢进度, 因为工作实在很忙, 业余也没有太多时间.
引擎设计跟踪(九.14.2i) Android GLES 3.0 完善的更多相关文章
- 引擎设计跟踪(九.14.2a) 导出插件问题修复和 Tangent Space 裂缝修复
由于工作很忙, 近半年的业余时间没空搞了, 不过工作马上忙完了, 趁十一有时间修了一些小问题. 这次更新跟骨骼动画无关, 修复了一个之前的, 关于tangent space裂缝的问题: 引擎设计跟踪( ...
- 引擎设计跟踪(九.14.2f) 最近更新: OpenGL ES & tools
之前骨骼动画的IK暂时放一放, 最近在搞GLES的实现. 之前除了GLES没有实现, Android的代码移植已经完毕: [原]跨平台编程注意事项(三): window 到 android 的 移植 ...
- 引擎设计跟踪(九.14.2h) 开发计划
以后的开发计划: 完善game runtime code, 跑简单的demo目前只有编辑器的运行流程, 没有游戏/demo流程, 图形的测试主要在编辑器上测试, 现在需要测试android系统的图形, ...
- 引擎设计跟踪(九.14.2g) 将GNUMake集成到Visual Studio
最近在做纹理压缩工具, 以及数据包的生成. shader编译已经在vs工程里面了, 使用custom build tool, build命令是调用BladeShaderComplier, 并且每个文件 ...
- 引擎设计跟踪(九.14.2d) [翻译] shader的跨平台方案之2014
Origin: http://aras-p.info/blog/2014/03/28/cross-platform-shaders-in-2014/ 简译 translation: 作者在2012年写 ...
- 引擎设计跟踪(九.14.2b) 骨骼动画基本完成
首先贴一个介绍max的sdk和骨骼动画的文章, 虽然很早的文章, 但是很有用, 感谢前辈们的贡献: 3Ds MAX骨骼动画导出插件编写 1.Dual Quaternion 关于Dual Quatern ...
- 引擎设计跟踪(九.14.3.4) mile stone 2 - model和fbx导入的补漏
之前milestone2已经做完的工作, 现在趁有时间记下笔记. 1.设计 这里是指兼容3ds max导出/fbx格式转换等等一系列工作的设计. 最开始, Blade的3dsmax导出插件, 全部代码 ...
- 引擎设计跟踪(九.14.2 final) Inverse Kinematics: CCD 在Blade中的实现
因为工作忙, 好久没有记笔记了, 但是有时候发现还得翻以前的笔记去看, 所以还是尽量记下来备忘. 关于IK, 读了一些paper, 觉得之前翻译的那篇, welman的paper (http://gr ...
- 引擎设计跟踪(九.14.2j) TableView工具填坑以及多国语言
Blade的UI都是预定义的接口, 然后由插件来负责实现, 目前只有MFC的插件. 最近加上了TableView的视图, 用于一些文件的查看和编辑, 比如前面在文件包的笔记中提到需写一个package ...
随机推荐
- php中关于抽象(abstract)类和抽象方法的问题解析
在面向对象(OOP)语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法作为外部代码访问的接口.而抽象方法就是为了方便继承而引入的,现在来看一下抽象类和抽象方法分别是如何定义以及他们的特点 ...
- ERROR 1045 (28000): Access denied for user root@localhost (using password:
错误描述: Mysql中添加用户之后可能出现登录时提示ERROR 1045 (28000): Access denied for user的错误.删除user.user中值为NULL的,或更新NULL ...
- 推荐个好东西swoole,php如虎添翼
Swoole:PHP语言的异步.并行.高性能网络通信框架,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列 ...
- delphi 基础之四 delphi 组织结构
delphi 组织结构 在Delphi中,一个正在开发的应用程序可以被称作项目或者工程.一般地,一个项目主要由dpr(项目).pas(单元)和dfm(窗体)三种文件组成,另外还有一些附属文件,如res ...
- 对于java反射的理解
java中的反射是一种强大的工具,它能够创建灵活的代码,这些代码可以在运行时装配,无序在组件之间进行链接. 反射允许在编写与执行时,使程序代码能够接入装载到JVM的类的内部信息,而不是源代码中选定的类 ...
- C#调用C++ Dll
现在项目基本都是旁边C++的哥们做好dll扔给我,然后我调用.好久之前晚上down了一份c#调用c++dll的方法,出处早已经遗忘.闲来无事,放上来好了.原作者看到后可以留言,我会把您链接放上的,帮了 ...
- 菜鸟学习Hibernate——缓存
Hibernate的缓存分为三种:一级缓存.二级缓存.查询缓存.下面我就为大家介绍一下. 一.概念. 一级缓存:第一级存放于session中称为一级缓存.Session 级别的缓存,它同session ...
- Linux 配置jdk环境变量
1.首先去官网下载所需版本的jdk,必须是.linux下的安装版本. 2.解压到以文件下 3.vim /etc/profile or ~/.bashrc 添加如下环境配置 JAVA_HOME=/usr ...
- 分享我常用的一些JS验证和函数
下面是我常用一些JS验证和函数,有一些验证我直接写到了对象的属性里面了,可以直接通过对象.方法来调用//浮点数除法运算 function fdiv(a, b, n) { if (n == undefi ...
- object sender ,EventArs e
引用:http://blog.csdn.net/kongbai308416350/article/details/4233786 说的通俗一些,就是: 有一个叫做EventHandler 的家伙,他会 ...