引擎设计跟踪(九.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 ...
随机推荐
- 使APP消除上方手机消息提示栏(显示WIFI,信号格那栏)消失的方法
public void toggleFullscreen(boolean fullScreen) { // fullScreen为true时全屏,否则相反 WindowManager.LayoutPa ...
- 【easyui】--普通js中获取easyui中分页信息(page,pageSize等)
对于datagrid,获取其分页信息: 方法: var pageopt = $('#list_data').datagrid('getPager').data("pagination&quo ...
- 下一代NoSQL:最终一致性的末日
相比关系型数据库,NoSQL解决方案提供了shared-nothing.容错和可扩展的分布式架构等特性,同时也放弃了关系型数据库的强数据一致性和隔离性,美其名曰:"最终一致性". ...
- Linux之kernal分析与启动20160610
说一下LINUX内核的分析与启动: 一. 内核启动流程,据此配置内核(机器ID) 1.1 修改Makefile 1.2 选择默认配置 : make s3c2410_defconfig 1.3 make ...
- JQuery中ajax跨域问题
var url = "http://apis.juhe.cn/idcard/index?key=e0a6277420506b2816b82f7d7821976c&cardno=&qu ...
- StyleCop学习笔记——初识StyleCop
一.定义 StyleCop是微软的一个开源的静态代码分析工具,检查c#代码一致性和编码风格. 二.支持的环境. JetBrains R# 5.1.3 ( 5.1.3000.12) JetBrains ...
- linux 下的使用 ln 创建 软链接 和 硬链接
linux 下的一个指令 ln 作用: 创建软链接或者硬链接 Linux 系统下每创建一个文件,系统都会为此文件生成一个 index node 简称(inode) ,而每一个文件都包含用户数据(use ...
- Oracle ClusterwarePRCT-1011 : Failed to run "oifcfg".&nb
OS: Oracle Linux Server release 6.3 DB: Oracle 11.2.0.3 在oracle-linux6.3安装11g RAC,在安装软件时候提示: An inte ...
- chkconfig 命令详解
chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法: chkconfig [--a ...
- 019C#中使用移位运算符获取汉字编码值
在进行移位运算时,当数值的二进制数每次向左移1位就相当于乘以2,当数值每次向右移一位就相当于除以2 private void button1_Click(object sender, EventArg ...