2012-10-03 82 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

相关问题