6

我目前正在开发一个使用 OpenGL ES 1.0 来渲染一些基本纹理的 iOS 应用程序(iPad 和 iPhone)。我使用图集来存储和呈现我的纹理。

我的主要图集相对较大(2000x2000),但我的内部算法会加载纹理并将其大小调整为 2048x2048,因为 OpenGL ES 仅接受 2 大小纹理的功率。我可以画瓷砖,这边一切都很好。

每次尝试加载和卸载(销毁)纹理时,我都会面临严重的内存泄漏。这应该在最终版本中发生,但我需要确保我的加载和卸载都很好。在内存中,纹理占用 2048x2048x4 (RGBA) 字节 = 大约 16MB。这是一个巨大的字节数,所以你明白这个问题对我来说很烦人(iOS 在几分钟后杀死了应用程序..)

当我加载纹理时,Instruments 表明应用程序使用的总内存增加了 16MB,这是正确的(我使用“Real Memory”列)。当我需要破坏纹理以释放它使用的所有可能字节时,就会出现问题:它永远不会丢失 16MB ......并且由于我在循环中加载和卸载,内存一直被使用并且从未被释放。

这是我加载纹理的方式:

GLubyte *outData = malloc((_dataWidth * _dataHeight * 4) * sizeof(*outData));
GLuint _texture; // declared as un instance variable so its address never changes
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D, _texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _dataWidth, _dataHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, outData);
free(outData);

这是我卸载纹理的方式(这被称为,我检查过)

glDeleteTextures(1, &_texture);

我到处使用 glGetError() 来检查是否发生错误,但它总是返回 0(即使在 glDeleteTexture 之后)。

有人有想法吗?谢谢!

4

2 回答 2

14

确保在创建上下文的同一线程上销毁纹理。如果您在没有上下文的情况下进行任何 GL 调用,则不会出现错误。

于 2012-04-20T14:33:37.040 回答
1

你试过GL_APPLE_client_storage扩展吗?这意味着您承诺保持传递给glTexImage2D活动的数据块直到glDeleteTextures被调用,而不是让 OpenGL 拥有纹理内存的副本。

于 2012-04-20T14:05:39.213 回答