我注意到当我加载几十个纹理时,我的应用程序崩溃,没有任何通知等。它只是返回到手机的上一个屏幕。难道是因为手机无法在内存中存储太多内容吗?我应该在游戏开始之前不加载所有纹理吗?加载数十个纹理后,应用程序崩溃
回答
你有你的答案已经作为评论的一部分,但我会在这里写这样的结论:
资产的存储的大小并不重要,因为它们可能被压缩。重要的是实际工作集的大小。在图像的情况下就可以计算出它作为
width * height * sizeof(pixel)
其中
sizeof(pixel) = sum[channels]{ sizeof(channel) }
在1024×1024,4个通道(RGBA),每个信道1个字节的单个纹理的你的工作集大小的情况下将是:
1024*1024 = 1Mi
1Mi * 4 * 1B = 4MiB
在27纹理的情况下,这相当于27*4MiB = 108MiB
。现在OpenGL根据抽象机器来定义,这意味着你不能问它,有多少内存需要花费。它只会告诉你它是否耗尽内存。如果不是所有东西都适合视频RAM,OpenGL也可以使用普通的系统RAM。无论哪种方式,如果试图上传超过100MiB的纹理数据,在手持设备上,您可能会耗尽内存。
在游戏开始之前我不应该加载所有纹理吗?
不,你不应该。事实上,“流”你的游戏内容,按需加载东西更好。另外某种垃圾收集或回收计划也有很大帮助。分配纹理非常昂贵(即调用glTexImage),而替换数据便宜(glTexSubImage),所以我建议在纹理管理结构中添加一个“未使用”的计数器。每次绑定纹理并从中拉出时,都将其设置为零。在完成帧增量后,每个纹理对象的“未使用”计数器。如果你需要加载一个新的纹理来迭代所有的纹理对象,选择那些匹配的格式(大小和通道数量相同),按未使用的计数器排序,然后重复使用纹理对象的“未使用”值,即在排序的“未使用”集的中间。每个“更高的未使用”质地应该被释放,其他人留作储备。如果您需要首先分配来自N个中值对象的多个纹理(可能)。使用该策略可以使您随时可以使用纹理对象,并且偶尔还可以释放未使用的内存。
为了回顾评论,在RGBA模式下,通过分配可能的纹理,共计27个1024 x 1024像素,每次纹理分配4 MB视频RAM,总共110 MB。
为了避免这种崩溃并与多个Android系统兼容,您应该缩小纹理的大小(有时会降低整体质量)。
毫无意义的是,纹理必须在不再使用时才被卸载,以便为其他新负载腾出空间。
- 1. 加载纹理SFML导致程序崩溃
- 2. 加载xib崩溃的应用程序
- 3. 应用程序崩溃后
- 4. 加载图片后应用程序崩溃
- 5. 加载600行后UITableview页面崩溃应用程序
- 6. 加载soundPool文件后的应用程序崩溃482次
- 7. 搜索后重新加载视图崩溃应用程序
- 8. 加载图像后应用程序崩溃
- 9. Android应用程序:在后台崩溃,然后再次崩溃
- 10. 使用NSKeyUnarchiver加载数据时应用程序崩溃
- 11. 开始崩溃3d后党的应用程序,该应用程序崩溃
- 12. 禁用弧后应用程序崩溃
- 13. 加载多个PNG图像时应用程序崩溃
- 14. 我想加载一个片段,但应用程序崩溃
- 15. BlackBerry 10 QML应用程序在数据源上崩溃加载
- 16. 访问崩溃应用程序崩溃应用程序内ios
- 17. 应用程序崩溃 - 有线崩溃
- 18. Android应用程序的负载崩溃
- 19. Tomcat 7自动添加一个web应用程序后崩溃
- 20. 添加第二个按钮后,Android应用程序崩溃
- 21. NSFileManager崩溃在应用程序代理
- 22. Android - 处理应用程序崩溃
- 23. 应用程序崩溃没有理由
- 24. 管理应用程序崩溃
- 25. Laravel 5.2添加到数据库后应用程序崩溃
- 26. 应用程序在启动后崩溃
- 27. 睡觉后应用程序崩溃
- 28. 几秒钟后应用程序崩溃
- 29. 重命名后应用程序崩溃
- 30. 更新应用程序后崩溃
请报告纹理的大小,它们的数量和代码的摘录,以更好地帮助你:) 这样就好像,我的车没有启动,是什么问题? :) :) – 2012-01-08 13:04:40
也发布崩溃日志 – nandeesh 2012-01-08 13:06:07
纹理的总大小为3.2mb,平均每个图像100kb。共有27个PNG,分辨率为1024 x 1024。 – 2012-01-08 13:37:19