opengl es如何释放纹理内存

st50886160 2010-09-16 09:49:36
我的问题:
我目前接触一个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的搜索组建(位于顶部的搜索框框)
此种情况我又不需要释放内存 郁闷 求解



...全文
2715 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
aiyongyyy 2012-09-17
  • 打赏
  • 举报
回复
楼主 不用每次都loadTexture的,一次loadTexture之后就可以了
xqhrs232 2011-07-27
  • 打赏
  • 举报
回复
也有类似的问题
st50886160 2010-09-28
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 yingwei19800524 的回复:]

。。。版主应该学习OPENGL ES的开发,再来发表,好像什么都不懂。。。。
[/Quote]
没看懂我的问题 别乱说什么
yingwei19800524 2010-09-21
  • 打赏
  • 举报
回复
。。。版主应该学习OPENGL ES的开发,再来发表,好像什么都不懂。。。。
st50886160 2010-09-20
  • 打赏
  • 举报
回复
虽然没有得到什么好的结果但是还是谢谢大家
yyy025025025 2010-09-17
  • 打赏
  • 举报
回复
感觉如果不在onStop中加入finish的话。

按照onResume,onPause的流程来跑的,你的代码就没有内存的问题了啊。

能否解释下,为什么需要这么做呢?
莫名的码农 2010-09-16
  • 打赏
  • 举报
回复
不是有serfaceDestroy()吗
freshui 2010-09-16
  • 打赏
  • 举报
回复
3G我不太清楚。

按home键,只是把桌面调到前端显示, 这时你的activity是调了 onPause,但是再进去,不会调用onCreate和OnStart。

具体你可以看看sdk文档中 Activity lifecycle那张图。

出问题肯定是你流程没有处理好。
st50886160 2010-09-16
  • 打赏
  • 举报
回复
看我对问题描述的那么清楚 希望得到高人的解答.....
charles_lc 2010-09-16
  • 打赏
  • 举报
回复
1. 我的意思是 你在Activity的onPause调用了GLSurfaceView的onPause函数没?在Activity的onResume调用了GLSurfaceView的onResume函数没?
2. 如果你遵循了Acitvity和GLThread同步 在resume的时候 纹理不会消失 如果你在onStop里面写了finish 那自然只能重新开始了 然后你也并没有释放内存 同时GLThread依然在运转 容易出现卡死的情况
3. 我还是不太清楚你到底想实现什么 能否简单的表达一下 Android并不会不考虑释放内存的问题 google那群人不是吃干饭的。。。
st50886160 2010-09-16
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 standatw 的回复:]
1.你在pause activity的时候同时pasue了GLThread没有?GLThread要和activity同步
2.按home键再回去不是直接执行oncreate 除非进程完全被杀掉
3.你用了glDeleteTextures没? 删除texture的时候要删除对应的buffer还要调用glDeleteTextures
4.如果你要更有效的控制memory 建议你用ndk

……
[/Quote]
1:请看再pause中释放内存,又很多不定因素,因为很多东西触发onpause函数 我第三小结有说到
2:我再Activity的onStop 里面写的finish() 请看8楼
3:glDelteTexture 释放内存没错 ,但是我们只能再用户不需要纹理的时候释放,就是说当前Activity失去焦点的时候释放, Activity失去焦点分别会调用onPause与onStop 请看蓝色字第三部分
4:4点建议不错,可惜我C不好......
charles_lc 2010-09-16
  • 打赏
  • 举报
回复
1.你在pause activity的时候同时pasue了GLThread没有?GLThread要和activity同步
2.按home键再回去不是直接执行oncreate 除非进程完全被杀掉
3.你用了glDeleteTextures没? 删除texture的时候要删除对应的buffer还要调用glDeleteTextures
4.如果你要更有效的控制memory 建议你用ndk

个人意见~
  • 打赏
  • 举报
回复
“操”字用的非常生动形象!
st50886160 2010-09-16
  • 打赏
  • 举报
回复
freshui 同学 我这个做是刻意的

我在onStop生命周期 写了finish()

按道理回到主界面再返回应用应该会进OnResume() 但是opengl 的话不允许这样做
因为再次返回进OnResume 纹理就全部消失了..... 但是内存依然没释放 纠结吧?
st50886160 2010-09-16
  • 打赏
  • 举报
回复
这内存释放真的是一个无底洞 android既然不让我们控制home键
最起码让我们知道 用户是否点击了Home吧
st50886160 2010-09-16
  • 打赏
  • 举报
回复
serfaceDestroy()进这个函数 的时候 就已经无法声请渲染了....... 自己试下吧

80,351

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧