GLenum _error_code = glGetError();
( _error_code != GL_NO_ERROR)
{
const
char
* extString = (
*)glGetString(GL_EXTENSIONS);
(
strstr
(extString,
"GL_OES_depth24"
) != 0)
{
glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT24_OES,(GLsizei)powW,(GLsizei)powH);
}
else
{
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,m_uDepthRenderBufffer);
(uDepthStencilFormat == GL_DEPTH24_STENCIL8)
{
glGenRenderbuffers(1,&m_uStencilRenderBufffer);
glBindRenderbuffer(GL_RENDERBUFFER,m_uStencilRenderBufffer);
_error_code = glGetError();
(_error_code == GL_NO_ERROR)
{
}
}
#endif
}
else
{
(uDepthStencilFormat == GL_DEPTH24_STENCIL8)
{
}
(3). 动态设置帧率
UI界面帧率设置最高30帧
战斗等特效和动画比较多的界面帧率设置最高60帧
(4). 自动裁剪
在一些大地图中,显示在屏幕外的纹理元素不添加到自动批渲染队里中。
(5).减少特效粒子数和帧数
把一些特效和帧动画改成骨骼动画,减少帧数量。
跟美术和策划沟通,在效果可接受的情况下减少特效粒子数。
2. 内存优化
由于我们游戏前期这方面做的工作不多,后期随着游戏内容的丰富,内存消耗越来越大,导致在一些低端机出现卡顿,切换到后台,进程经常被系统kill。优化方案如下:
(1)纹理压缩
压缩后的纹理直接使用gpu解码,不需要cpu解码展开再传输至gpu,极大减少内存,减少cpu计算,加快纹理加载速度。
格式:
android使用etc1,工具:Mali Texture Compression Tool
ios使用pvrtc4,工具:TexturePacker
内存占用:
ETC1占用内存跟图片尺寸有关,每个像素占0.5个字节,占用磁盘空间会比png8大。
PVRTC每个像素0.25~0.5个字节 (pvrtc2和pvrtc4)
其他常见纹理格式(2~4个字节)如图:
下面是在Android平台上纹理压缩实现步骤:
1. 使用TexturePacker把要压缩的散图,打包生成png和plist文件。
2. 使用pkm批处理工具,遍历和解析资源目录下的plist文件,根据plist中的png大图(textureFileName的值)生成同名pkm文件,这里需要注意的是生成pkm文件的时候根据情况选择是否创建带alpha部分,因为etc1本身不支持透明图片,使用mali工具生成一张拼接在一起的纹理,这张纹理上半部分是原始图片(无alpha信息),下半部分是alpha信息图片。带有alpha信息的pkm
图片在渲染的时候使用特殊的shader进行渲染,后缀名使用.pkm,不带alpha信息的图片后缀使用.pkm0。
带alpha信息
etcpack.exe %1 %2 -v -c etc1 -aa -s fast
不带alpha信息
etcpack.exe %1 %2 -v -c etc1 -s fast
3. 编写顶点shader和片段shader,在顶点着色器中得到原图纹理坐标和带有alpha信息的纹理坐标,然后在片段着色器中对纹理进行采样,预乘alpha。
4. 使用shader,因为游戏中有些图片没有进行纹理压缩,所以这里要在精灵类的initWithTexture函数中根据纹理名后缀进行区分使用哪个shader,在CCNodeLoader::parsePropTypeSpriteFrame)ccb加载的时候也需要根据是否有plist文件判断使用哪个shader。
5. 把plist中key为textureFileName的值的后缀由png替换成pkm或pkm0。
(2)使用texturepacker拼图
用texturepacker把一些小散图打包到一张大图,减少纹理IO和draw call。
(3)使用对象池
在需要频繁创建对象的场景中,使用对象池。
(4)UI(button,非渐变背景)使用九宫格
(5) 切换场景时释放无用纹理
1
2
CCTextureCache:sharedTextureCache():removeUnusedTextures();
CCTextureCache:sharedTextureCache():dumpCachedTextureInfo();
|
(6)整理常驻内存UI资源
把主界面底部共用菜单等界面资源打包成一张纹理,常驻内存,省去加载和重新创建纹理的开销。
3. 遇到的坑
(1) 游戏使用luajit后,crash率上升了不少。
原因:因为luajit不支持c++方式编译。在lua的c代码中,如果遇到错误会使用luaL_error来报错。通常lua是以c的方式来编译的,luaL_error最终会调用longjump来实现函数远程跳转,而这种调转不遵循c++关于stack unwinding的规范,cocos2dx是使用c++语言编写的。这个会直接导致在调了luaL_error之后对象不会被析构(一般会在对象的析构函数中做一些处理,如重置状态和释放资源等)。在对这个没有被析构的对象上循环执行一些图像操作时可能会导致crash。分析游戏crash上报日志发现,多数crash发生在MTK芯片设备上的/system/vendor/lib/egl/libGLESv2_mtk.so模块中和一些opengl操作上。
解决方案:使用官方版的luac替代luajit,并使用c++的方式编译。
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!