alo*_*oko 11 iphone ios opengl-es-2.0 ios5 glkit
在iOS 5上开发新功能,特别是iOS 5上新的OpenGL相关功能,所以如果我的任何问题都是如此基本,我会道歉.
我正在处理的应用程序旨在接收相机帧并通过OpenGL ES在屏幕上显示它们(图形人员将接管这个并添加我知道的实际OpenGL绘图).该应用程序是开发XCode4,目标是运行iOS 5的iPhone4.目前,我使用ARC和GLKit功能,除了在将图像加载为纹理时的内存泄漏,所有工作都正常.该应用程序很快就会收到"内存警告".
具体来说,我想问一下如何释放分配的纹理
@property(retain) GLKTextureInfo *texture;
-(void)setTextureCGImage:(CGImageRef)image
{
NSError *error;
self.texture = [GLKTextureLoader textureWithCGImage:image options:nil error:&error];
if (error)
{
NSLog(@"Error loading texture from image: %@",error);
}
}
Run Code Online (Sandbox Code Playgroud)
这image
是一个由相机框架构建的石英图像(来自苹果的示例代码).我知道问题不在代码的那一部分,因为如果我禁用分配,应用程序不会收到警告.
alo*_*oko 22
我相信超级hacky解决方案,但它似乎工作:
在分配之前添加以下内容:
GLuint name = self.texture.name;
glDeleteTextures(1, &name);
Run Code Online (Sandbox Code Playgroud)
如果有更正式的方式(或者如果这是官方的方式),如果有人能让我知道,我将不胜感激.
不是直接的答案,而是我注意到的东西,它不适合评论.
如果您正在使用GLKTextureLoader
在背景中加载纹理来替换现有纹理,则必须删除主线程上的现有纹理.删除完成处理程序中的纹理将不起作用.
AFAIK这是因为:
也就是说,这会泄漏内存.
NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft:@YES};
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[self.asyncTextureLoader textureWithContentsOfFile:@"my_texture_path.png"
options:options
queue:queue
completionHandler:^(GLKTextureInfo *texture, NSError *e){
GLuint name = self.myTexture.name;
//
// This delete textures call has no effect!!!
//
glDeleteTextures(1, &name);
self.myTexture = texture;
}];
Run Code Online (Sandbox Code Playgroud)
要解决此问题,您可以:
因此,要修复泄漏,您需要这样做:
//
// Method #1, delete before upload happens.
// Executed on the main thread so it works as expected.
// Potentially leaves some GL content untextured if you're still drawing it
// while the texture is being loaded in.
//
// Done on the main thread so it works as expected
GLuint name = self.myTexture.name;
glDeleteTextures(1, &name)
NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft:@YES};
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[self.asyncTextureLoader textureWithContentsOfFile:@"my_texture_path.png"
options:options
queue:queue
completionHandler:^(GLKTextureInfo *texture, NSError *e){
// no delete required, done previously.
self.myTexture = texture;
}];
Run Code Online (Sandbox Code Playgroud)
要么
//
// Method #2, delete in completion handler but do it on the main thread.
//
NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft:@YES};
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[self.asyncTextureLoader textureWithContentsOfFile:@"my_texture_path.png"
options:options
queue:queue
completionHandler:^(GLKTextureInfo *texture, NSError *e){
// you could potentially do non-gl related work here, still in the background
// ...
// Force the actual texture delete and re-assignment to happen on the main thread.
dispatch_sync(dispatch_get_main_queue(), ^{
GLuint name = self.myTexture.name;
glDeleteTextures(1, &name);
self.myTexture = texture;
});
}];
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6089 次 |
最近记录: |