2012-05-06 43 views
1

我尝试在cocos2d的后台线程中渲染纹理,并且运行良好,除了由于某些原因我不能在不再使用时释放纹理。CCRenderTexture吃掉了我的记忆

首先加载两个图像异步,然后我运行后台任务,我渲染一个新的图像。正如我所说的,它工作得很好,问题是我的应用程序在几次调用这些函数后崩溃。我不知道如何做更多的清理。记录我的可用内存告诉我,我每次在10-15 mb之间都会丢失(gfx1和gfx2是视网膜全屏背景)。

问题必须在这些代码行中,因为当我删除它们时,我不再有内存问题,并且对我的应用程序进行分析表示没有泄漏!

纹理是NSMutableArray。我在索引0处有一个纹理,渲染一个新的纹理并将它添加到位置1.替换精灵后,我尝试在索引0处杀死我的(现在是旧的)纹理,并且我的新纹理变为索引0,所以我可以运行这个功能重新开始。

所以这里是代码

- (void) startBuildingTextureInBackground { 
    [[CCTextureCache sharedTextureCache] addImageAsync:@"gfx1.png" 
               target:self 
               selector:@selector(imageLoaded:)]; 
} 

- (void) imageLoaded: (id) obj { 
    rtxTexture1 = [[CCTextureCache sharedTextureCache] textureForKey:@"gfx1.png"]; 
    [[CCTextureCache sharedTextureCache] addImageAsync:@"gfx2.png" 
               target:self 
               selector:@selector(imageLoaded2:)]; 
} 

- (void) imageLoaded2: (id) obj { 
    rtxTexture2 = [[CCTextureCache sharedTextureCache] textureForKey:@"gfx2.png"]; 
    [self performSelectorInBackground:@selector(buildRtxTexture) withObject:nil]; 
} 

- (void) buildRtxTexture { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    EAGLSharegroup *sharegroup = [[[[CCDirector sharedDirector] openGLView] context] sharegroup]; 
    EAGLContext *k_context = [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:sharegroup] autorelease]; 
    [EAGLContext setCurrentContext:k_context]; 
    [[CCDirector sharedDirector] setGLDefaultValues]; 

    CCSprite* gfx1 = [CCSprite spriteWithTexture:rtxTexture1]; 
    [rendernode addChild:gfx1]; 

    CCSprite* gfx2 = [CCSprite spriteWithTexture:rtxTexture2]; 
    [rendernode addChild:gfx2]; 

    CCRenderTexture* rtx = [CCRenderTexture renderTextureWithWidth:512 
                  height:320 
                 pixelFormat:kTexture2DPixelFormat_RGBA4444]; 

    [rtx beginWithClear:0 g:0 b:0 a:0]; 
    [rendernode visit]; 

    [rtx end]; 

    [rendernode removeChild:gfx1 cleanup:YES]; 
    [rendernode removeChild:gfx2 cleanup:YES]; 

    [[CCTextureCache sharedTextureCache] removeTexture:rtxTexture1]; 
    [[CCTextureCache sharedTextureCache] removeTexture:rtxTexture2]; 

    [EAGLContext setCurrentContext:nil]; 
    [self performSelectorOnMainThread:@selector(textureLoaded:) withObject:rtx.sprite.texture waitUntilDone:YES]; 

    [pool release]; 
} 

- (void) textureLoaded:(CCTexture2D*) newTexture { 
    [textures addObject:newTexture]; 
} 

- (void) replaceTexture { 
    if (rtxSprite != nil) { 
     [spriteDisplay removeChild:rtxSprite cleanup:YES]; 
     [[CCTextureCache sharedTextureCache] removeTexture:[textures objectAtIndex:0]]; 
     [textures removeObjectAtIndex:0]; 
    } 

    rtxSprite = [CCSprite spriteWithTexture:[textures objectAtIndex:0]]; 
    rtxSprite.scaleY = -1; 
    [spriteDisplay addChild: rtxSprite]; 
} 

回答

0
  1. 尝试调试代码:添加断点或数据的NSLog/CCLOG的跟踪CCTexture2D/CCRenderTexture的init/dealloc的方法的调用。

  2. 您在后台线程中存在CCRenderTexture问题。当我尝试使用CCRenderTexture来操作纹理时,结果出乎意料(黑色纹理或崩溃)。这是因为在主循环中调用OpenGL函数也是,而OpenGL是状态机。解决方法是在主线程(performSelectorOnMainThread)中用CCRenderTexture调用方法。

0

在将上下文设置为零之前调用[pool release]解决了问题。