读书人

opengl es怎么释放纹理内存

发布时间: 2012-09-27 11:11:17 作者: rapoo

opengl es如何释放纹理内存
我的问题:
我目前接触一个3D开发 里面需要创建很多纹理 并且这个纹理所占内存特别的大

假设我的控制3D的Activity为3DActivity 当然他setContentView(new GLSurfaceView());代表3D嘛

当实例化这个3DActivity的时候 也就意味着已经加载了非常多的纹理(程序需要)

当我点击Home的时候 就回到主界面了 又再次长按Home 回去之前的 3DActivity (这样又重新onCreate onStar.....)

重新回到3DActivity的时候 你再次创建纹理ID 又会从0开始 意味着你已经无法再释放之前的纹理ID了 只能让系统释放了

这样反复操作(退出又返回)你的应用将会报OutOfMemory异常 主要原因是因为android没即时释放纹理ID所指定的内存


我的解决方案:

接触opengl es的可能知道 非GLThread是无法删除纹理ID的(我没理解错吧?)

非GLThread无法删除 就是说只能再onDrawFrame() onSurfaceChanged() onSurfaceCreated()中进行gl相关操作

因此我的做法是再GLSurfaceView中绘图函数这样做
public void onDrawFrame(GL10 gl) {
if(isNeedReleaseMemory){
//删除纹理ID
}
}

isNeedReleaseMemory是一个boolean类型变量,只需要捕获到用户有切换Activity的意向我就吧此变量设置为true
然后向GLSurfaceView声请渲染,这样纹理就删除了......


我的解决方案所产生的问题:
我们无法捕获Home 只知道按下Home会触发3DActivity 的 onPause() onStop(),因此我们考虑再这2函数内请求释放内存

onStop:在onStop中不考虑 因为你再此函数将isNeedReleaseMemory=true 然后再声请渲染 它不会渲染了(进onDrawFrame 函数).


onPause:在onPause中 isNeedReleaseMemory=true 声请渲染会调用onDrawFrame 函数 意味纹理会被释放


问题就出再很多地方都可以引发onPause() 比如按睡眠键 以及触发android的搜索组建(位于顶部的搜索框框)
此种情况我又不需要释放内存 郁闷 求解




[解决办法]
1. 我的意思是 你在Activity的onPause调用了GLSurfaceView的onPause函数没?在Activity的onResume调用了GLSurfaceView的onResume函数没?
2. 如果你遵循了Acitvity和GLThread同步 在resume的时候 纹理不会消失 如果你在onStop里面写了finish 那自然只能重新开始了 然后你也并没有释放内存 同时GLThread依然在运转 容易出现卡死的情况
3. 我还是不太清楚你到底想实现什么 能否简单的表达一下 Android并不会不考虑释放内存的问题 google那群人不是吃干饭的。。。

读书人网 >Android

热点推荐