2012-10-03 79 views
1

我幾乎完成了我的應用程序。其中一個觀點使用GLKit。我只是有內存問題。基本上發生的是,當顯示GLKView時,內存消耗量不斷增加(見Instruments)。在某個時候它顯然崩潰了。 我對GLKit不太瞭解,所以我希望你能幫助我。內存使用量不斷增加(GLKit - iOS)

問題是我正在顯示的3d箭頭。如果我不繪製它,所有其他的東西都不會產生任何問題。 這是包含箭頭頂點數據頭文件:

#import <GLKit/GLKit.h> 

struct arrowVertexData 
{ 
    GLKVector3  vertex; 
    GLKVector3  normal; 
    GLKVector2  texCoord; 
}; 
typedef struct arrowVertexData arrowVertexData; 
typedef arrowVertexData* vertexDataPtr; 


static const arrowVertexData MeshVertexData[] = { 
    {/*v:*/{{-0.000004, 0.0294140, -0.0562387}}, /*n:*/{{0.000000, 1.000000, 0.000000}}, /*t:*/{{0.500000, 0.333333}}}, 
... etc... 

這是抽獎代碼:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    [self.arrowEffect prepareToDraw]; 
    //glGenVertexArraysOES(1, &arrowVertexArray); 
    //glBindVertexArrayOES(arrowVertexArray); 

    glGenBuffers(1, &arrowVertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, arrowVertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(MeshVertexData), MeshVertexData, GL_STATIC_DRAW); 

    glEnableVertexAttribArray(GLKVertexAttribPosition); 
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(arrowVertexData), 0); 
    glEnableVertexAttribArray(GLKVertexAttribNormal); 
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_TRUE, sizeof(arrowVertexData), (void *)offsetof(arrowVertexData, normal)); 
    glBindVertexArrayOES(arrowVertexArray); 

    // Render the object with GLKit 

    glDrawArrays(GL_TRIANGLES, 0, sizeof(MeshVertexData)/sizeof(arrowVertexData)); 

    //reset buffers 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

    //disable atttributes 
    glDisableVertexAttribArray(GLKVertexAttribNormal); 
    glDisableVertexAttribArray(GLKVertexAttribPosition); 
} 

什麼建議嗎? 非常感謝您的幫助!

+1

謝謝,我現在做了。 – Davide

回答

2

您每次調用drawInRect時都會創建一個新的頂點緩衝區(VBO),並且從不刪除它們。 GLGenBuffers和GLBindBuffer設置了一個新的緩衝區並使其成爲最新的,但真正的損害是通過GLBufferData完成的,其中的數據複製到新的緩衝區中。

glBindBuffer(GL_ARRAY_BUFFER,0);將GL重置爲不使用緩衝區,glDisableVertexAttribArray(GLKVertexAttribPosition);告訴GL不再在緩衝區中查找位置數據,但這些調用都不會執行任何操作來釋放內存。如果你想每次釋放內存,你需要調用GLDeleteBuffers(1,& arrowVertexBuffer);釋放內存。

更好的方法是在啓動時生成一次緩衝區,並在終止時將其刪除,然後掛在箭頭VertexBuffer上,每次重新綁定和解除綁定,如重置指針一樣銷售,假設其他部分程序正在修改GL狀態。

它看起來像你也開始使用頂點數組對象(VAO)的路徑,這將是捕捉狀態一次以供重用的另一種方式,不過最好等到VBO正常工作試圖。 VBO和VAO都是緩存隨着時間推移發展的狀態的方法,以減少每次通過渲染循環的負載,但是VAO會投射更廣泛的網絡,這可能會讓它更加棘手。

作爲一般性建議,您可能可以通過添加更常用和更受歡迎的標籤(如[Open GL])來獲得更多關注。

你應該嘗試的另一個調試工具是OpenGL Profiler。如果您沒有使用XCode安裝它,請在文檔中查找它,並且您應該找到下載圖形工具軟件包的鏈接。資源窗口將允許您跟蹤正在使用的緩衝區對象。

0

您是否嘗試過在Xcode中運行靜態分析器?

這是非常好的指出分配的內存,沒有發佈和那種事情。

要使用它,請將鼠標按在「運行」按鈕上並從下拉列表中選擇「分析」。

如果它發現任何它通常指向出來的藍色,你可以看到追溯內存被分配在那裏,而不是釋放,等等

讓我知道,如果有任何影響的行。

+0

謝謝,但不幸的是,靜態分析儀沒有發現任何問題。 – Davide

相關問題