2010-02-16 37 views
0

我有一個很好很簡單的方法來加載我的iPhone應用程序中的紋理,其中我glGenTextures(13, &textures[0]);。當然,在這我做glDeleteTextures(13, textures);,但內存沒有完全釋放,直到我註釋掉該行末尾: CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), textureImage);'(其在具有紋理全黑當然結果),雖然下一行說:CGContextRelease();不釋放上下文?

CGContextRelease(textureContext); 

這是載入紋理的完整代碼:

- (void)loadTexture:(NSString *)name intoLocation:(GLuint)location { 
    CGImageRef textureImage = [UIImage imageNamed:name].CGImage; 
    if (textureImage == nil) { 
     NSLog(@"Failed to load texture image"); 
     return; 
    } 

    NSInteger texWidth = CGImageGetWidth(textureImage); 
    NSInteger texHeight = CGImageGetHeight(textureImage); 

    GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight << 2); 

    int k, l = texWidth * texHeight << 2; 
    for (k=0; k<l; k++) textureData[k] = 0; 

    CGContextRef textureContext = CGBitmapContextCreate(textureData, texWidth, texHeight, 8, texWidth << 2, CGImageGetColorSpace(textureImage), 
                 kCGImageAlphaPremultipliedLast); 
    CGContextTranslateCTM(textureContext, 0, texHeight); 
    CGContextScaleCTM(textureContext, 1.0, -1.0); 
    CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight), textureImage); 
    CGContextRelease(textureContext); 

    glBindTexture(GL_TEXTURE_2D, location); 
    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, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData); 

    free(textureData); 
    glEnable(GL_TEXTURE_2D); 
} 
+0

代碼看起來還行;你是如何確定有泄漏發生的? – 2010-02-16 17:59:18

+0

這種方法沒有泄漏。只是當我加載這樣的紋理時,我無法釋放我用來加載這些紋理的內存:| – Tom 2010-02-24 23:44:54

回答

0

CGImage解碼其數據懶洋洋地在第一時間的繪製。它保持已解碼的數據。

UIImage類通過名稱來緩存UIImage實例,並且這些實例持有保存解碼數據的CGImages。響應低內存警告清除UIImage緩存。

如果這導致您的應用程序使用太多的內存,您想要更仔細地控制UIImages的創建和銷燬,這意味着不使用+ [UIImage imageNamed:]。

另一方面,通常一個應用程序沒有許多命名的圖像 - 這是一個靜態集在編譯時確定。如果你只是想知道關於這種內存使用情況,那麼你去。

+0

感謝您的回覆。我的遊戲中沒有使用很多紋理(1MB),所以對我來說沒問題,但是因爲這個內存不能發佈,所以我想知道爲什麼這種加載紋理的方式在教程中很常見。 誰能推薦加載紋理的更好的辦法? – Tom 2010-02-24 23:45:58

+0

'+ [UIImage的imageNamed:]'很適合可可的應用程序,將繼續使用的圖像,沒有那麼對於你僅僅使用一次轉儲到一個紋理圖像。我不熟悉GL,所以我不確定什麼是最簡單的。你可以通過' - [NSBundle pathForResource:ofType:]'獲得圖像的路徑。如果您希望獲得圖像數據(採用磁盤格式),則可以使用' - [NSData initWithContentsOfFile:]'。如果UIImage很方便,而且你不喜歡緩存,那麼' - [UIImage initWithContentsOfFile:]'。 – Ken 2010-03-05 09:14:01