1

アプリをほぼ完成させました。ビューの 1 つは GLKit を使用します。記憶に問題があるだけです。基本的に何が起こるかというと、GLKView が表示されると、メモリ消費量が常に増加します (Instruments で見られます)。ある時点で明らかにクラッシュします。GLKit についてはよくわからないので、お役に立てれば幸いです。

問題は、表示している 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);
}

なにか提案を?助けてくれてどうもありがとう!

4

2 に答える 2

2

drawInRect が呼び出されるたびに新しい頂点バッファー (VBO) を作成し、それらを削除することはありません。GLGenBuffers と GLBindBuffer は、新しいバッファーをセットアップして最新の状態にしますが、実際の損傷は、データを新しいバッファーにコピーする GLBufferData で行われます。

glBindBuffer(GL_ARRAY_BUFFER, 0); バッファーを使用しないように GL をリセットし、glDisableVertexAttribArray(GLKVertexAttribPosition); バッファ内の位置データを検索しないようGLに指示しますが、これらの呼び出しのどちらもメモリを解放するために何もしません。毎回メモリを解放したい場合は、GLDeleteBuffers(1, &arrowVertexBuffer); を呼び出す必要があります。メモリを解放します。

より良いアプローチは、起動時に一度バッファーを生成し、終了時に削除し、arrowVertexBuffer に固執し、必要に応じて毎回再バインドおよびバインド解除し、プログラムの他の部分が GL を変更していると仮定して、ポインターをリセットすることです。州。

また、Vertex Array Object (VAO) を使用する道を歩み始めたようです。これは、再利用のために状態を一度キャプチャする別の方法ですが、VBO が正しく機能するまで待ってから試行することをお勧めします。VBO と VAO はどちらも状態をキャッシュする方法であり、レンダリング ループのたびに負荷を軽減するために時間の経過とともに進化してきましたが、VAO ははるかに広いネットワークをキャストするため、正しく取得するのが難しくなる可能性があります。

一般的な提案として、[Open GL] などのより一般的で人気のあるタグを追加することで、このような質問に対してより多くの注意を引くことができる場合があります。

絶対に試すべきもう 1 つのデバッグ ツールは、OpenGL Profiler です。XCode と一緒にインストールしなかった場合は、ドキュメントを参照してください。グラフィック ツール パッケージをダウンロードするためのリンクが見つかります。リソース ウィンドウでは、使用中のバッファ オブジェクトを追跡できます。

于 2012-10-17T06:07:15.050 に答える
0

Xcode で静的アナライザーを実行してみましたか?

解放されていない割り当てられたメモリなどを指摘するのは非常に得意です。

それを使用するには、[実行] ボタンをマウスで押したままにして、ドロップダウン リストから [分析] を選択します。

何かが見つかった場合、通常はそれらを青色で示し、メモリが割り当てられていて解放されていない場所などにさかのぼる行を見ることができます...

それが何か効果があるかどうか教えてください。

于 2012-10-03T19:58:48.100 に答える