• 游戏平台移植经验(IOS)


            本人以前在移植3D游戏引擎到各个平台的时候遇到过不少问题,由于现在年事已高,记性较差,俗话说,好记性不如烂笔头。所以记录下来。但由于年代久远可能会记错或者已经不是问题的话,望大家多多包含。

    IOS篇:( 在IOS5.0以前的经验 )

      1:IOS系统是linux内核,在linux上wchar_t是4个字节,而在windows上是2个字节。以前是发现在引擎底层写死了,所以吃了大亏。

      2:IOS系统上opengles并不支持ETC的纹理格式,不过IOS系统的设备芯片都是power的,都支持power的纹理格式,硬件会压缩和解压power的纹理,非常的好用。想跨android和ios平台来统一纹理格式的话。可以在android上自己参加官方来做个power格式纹理的解压和压缩。虽然这样会降低一定的效率也是软解,但对于统一来说还是比较方便,跨平台嘛总是要取舍的,不然就只有另外做一套资源来用了。

      3:IOS系统上并不支持直接写屏,而是把东西画在Texture上的,但现在估计没人做这方面的优化了吧。并且在EGL配置上也会有很大的不同,像全屏抗锯齿这种东西,在IOS上以前我测试开了4倍采样就会非常的卡,当然2倍采样也是无法接受的。不知道现在怎么样,不过我估计也不会有很多人去开吧,这个算是个瓶颈。具体的EGL配置可能还需要大家去研究了。这里我就用到了这点。

      4:IOS系统上在顶点数据上并不支持halffloat,不知道现在改没有,这也是个优化,估计大家很少做,但要追求完美 这些东西都是必须要的。所以我们在后面就改成了float。

      5:IOS系统上在NOPT的支持上面有严格的要求,在我移植的时候NPOT只支持2D贴图并且还有一系列要求,不能有MIPMAP等。我把原文要求发下来了。大家可以观看。

      In the absence of OES_texture_npot, which lifts these restrictions, neither
        mipmapping nor wrap modes other than CLAMP_TO_EDGE are supported in 
        conjunction with NPOT 2D textures.  A NPOT 2D texture with a wrap mode that
        is not CLAMP_TO_EDGE or a minfilter that is not NEAREST or LINEAR is 
        considered incomplete.  If such a texture is bound to a texture unit, it is 
        as if texture mapping were disabled for that texture unit.
      
      所以如果要做npot的2D贴图的时候一定要记住以上的要求,其实最好的就是保守点好,不要压缩不要mip等。要么就是做成2次幂的贴图。以前有人说了很多关于ios上NPOT和2次幂贴图的比较,说NOPT贴图省内存等,其实这 些都是设计上的问题了。在实际测试上发现其实NPOT的贴图并没有想象的那么好,因为其实硬件会自动补齐这张贴图为2次幂贴图对于像素来说没有一点提升反而还会降低效率(我已经实际测试过这个了),那么对于内存的优化估计也没有想象的好。所以大家最好还是用2次幂贴图来做比较好,对于跨平台也是这样,你会发现在android上有一堆机子不支持nopt的贴图,到时候就是真是到处FUCK了。

     6: IOS系统上限帧是有要求的,必须是30的倍数,所以你设置45帧之类的它好像是不会认的,这是因为ios的displayLinker要做刷新同步。所以要么就是60要么就是30,我们设置的是30帧。这样的游戏也是差不多OK的。

     7: 用XCODE编译的时候用苹果自带的LLVM编译器会做相当大的优化,其实还有很多优化选项可以开,不过好像现在大多数人不是不去参考优化选项的,但这个的确可以提高很多性能哦,不过要注意其中编译选项的选择,不然可能会出现很多东西。

     8:在音频方面,我最开始是用的IOS本身系统的音频接口来写的,IOS原来支持一个MP3播放当背景音乐,音频格式也支持的比较少,同时播放的音频数量是也有上限的,我这里设置的16个。但我发现这样播放音频好像并没有传说中的流畅,虽然是硬解码。而且对于跨平台来说不方便,后来就改成了opengal来做。这对于3D游戏来说其实非常好用,因为他有3D音效,很多时候可以带来更多的立体感,对于跨平台来说也好用(android和windows上都可以找到库或者源码来编译),缺点就是他是软解,有些时候还是不太给力。这里也出现了关于openal的几个BUG(改这几个BUG的时候真尼玛的各种FUCK有木有)。
      第1:在音频BUFFER不够大的时候会出现崩溃的现象。但是在BUFFER够大的时候又会出现解码速度跟不上播放速度的情况。这尼玛是在玩我啊?所以找到一个合适的点很重要。。。。。这就是所谓的G点。。。
      第2:在前期做的时候由于经验不足并没有做缓冲处理,然后就各种崩崩崩的很开心了。后来做成了类似于双缓冲的形式来做,就跟网上视频缓冲差不多的原理来做,嘿嘿,这下我开心了。

     9:IOS系统上文件读写的时候有几点要注意。
      第1:IOS设备上文件是是区分大小写的,但是模拟器却是不区分大小写的。这尼玛绝对是坑爹的。并且资源文件在模拟器上是有缓存的,如果你删除的资源在模拟器上还会莫名其妙的显示,你一定会说:FUCK,这尼玛怎么回事。不过在我的地盘必须听我的,草,果断删除掉模拟器上的应用,我就是喜欢这么暴力,好,一切问题解决。这绝对不是坑爹可以形容的。
      (关于这点多谢老徐提醒,上面红色的文字有错误,模拟器是可以设置成区别大小写的,如下图)
      
      第2:在添加文件的时候xcode会问你是否是绝对路径?一定要仔细选择,绝对路径和相对路径。如果你选择的是绝对路径,那么要注意了,千万不要有重名文件,即使他们在不同的文件夹内,也是没用的,比如texture/cao.png,test/cao.png。系统他就只会认cao.png。太尼玛喜欢cao了。后来我在读取这个资源的时候,我发现一会显示的是黄色的草,一会显示的绿色的草。草啊,你以为你是在玩川剧的变脸啊。这个问题让我忧伤了很久,一定要注意。。。。
      第3:IOS的文件路径是分了可写和可读路径的,fwrite并不是不起作用,而是你没找到正确的路径。只有在可写路径的时候才会起作用。(关注fwrite要补充一点,在IOS上写最好是一次性写入,即使是数据很多的情况也最好这样做。如果分批写入就算是很少,如果写入次数很多就会造成很卡的情况,这个是IOS上的IO特性了,不同平台不一样的情况,并且在写入完后一定要flush才能写入成功,不然是不成功的。)
      第4:XCODE上面的资源不是所有拖进去的资源就是最终打包的资源,要在bundle里面检查才是最终的。

    10:真机和模拟器上的一些区别。
      第1:模拟器上是依赖的是MAC OS的系统环境,而真机上是纯正的IOS系统环境,所以在opengl的瓶颈和显示上会有很多的不同。一些opengl的函数由于驱动的处理会显示的不同。比如说一个UV会在模拟上正常,但在真机上却非常大。还有viewport其实已经设置错误了,但在模拟器上是检查不出来的,却在真机上会显示出来。还有在模拟器上骨骼已经错了或者已经超出上限,也是看不出来的。
      第2:内存上变量的初始化也会不同,如果一个变量不初始化,系统会自动初始化,在模拟器上应该是会是很正常的负数,而在设备上却会是有时候负数有时候整数,所以变量初始化一定要记得自己初始化。
      总的来说,模拟器上容错率是比较高的,而真机上比较严格。

    11:IOS由于本身系统上的版本的区别,驱动也会做出不同的处理,比如以前我们写的shader在ps上写的是highp,在ios4上的设备或者模拟器上显示正常。但在ios5上的设备上会发现掉帧非常的明显,后来改成lowp后就非常的顺畅。顶点精度上在不同的系统版本上也会有发现不同,如果只为了优化而把精度改成全低却会发现很明显的错误。后来就改成了mediump精度。后来有人测试过有些地方你改成lowp反而没有highp效率高,虽然原因不得而知,但这也是注意的地方。

    12: IOS和android上都是支持FBO的,也就是说你可以使用rendertarget来做一些东西,但是opengles2.0是不支持几个rendertarget一起渲染的,所以只能同时渲染1个。这2个平台也是支持VBO的,我们在IOS设备上曾经测试过使用VBO的数据,请看下图:
      
      从图中可以看出来VBO的使用的极限,还有其它数据的测试,比图说drawcall等。这里特别要注意的一点是在ios设备3GS以后贴图尺寸最大可以支持到2048*2048(再大的贴图我们没测试过了)。还有可以看出半透明是影响效率的一大很重要的瓶颈,在ipad1上严重可以看出其瓶颈。所以尽量少使用半透明的贴图也是关键优化的所在。
    
    
     
  • 相关阅读:
    2016.01.04接触spring一年开始读spring源码
    hibernate 各历史版本下载 spring各历史版本下载
    mongodb 安装使用遇到的问题记录
    EmEditor处理大文本文件
    linux的常用易忘命令
    签名的html
    添加用户-查看用户列表-禁止默认root登陆
    今天领导分享了一个探测端口的命令-linux下提示bash:command not found
    【原创】java 获取十个工作日之前或之后的日期(算当天)-完美解决-费元星
    Oracle 完全理解connect by-详细脚本-可实战
  • 原文地址:https://www.cnblogs.com/snowraindy2014/p/3616367.html
Copyright © 2020-2023  润新知