23

私のアプリケーションでは、glTexImage2D を広範囲に使用しています。画像の画像をコピーしてテクスチャとしてレンダリングします。マウスをクリックするたびに頻繁に実行します。レンダリング用のバイト配列として渡します。メモリが食い尽くされており、スワップ メモリも割り当てられています。メモリリークですか?それとも、 glTexImage2D が参照などを保持しているという事実によるものですか。

編集:

    //I allocate the memory once
    GLuint texName;
    texture_data = new GLubyte[width*height];

    // Each time user click I repeat the following code (this code in in callback)
    // Before this code the texture_data is modified to reflect the changes
    glGenTextures(3, &texname);
    glBindTexture(GL_TEXTURE_2D, texname);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,texture_data);

あなたのクローズリクエストとダウン投票が今すぐ停止されることを願っています!

4

1 に答える 1

49

glGenTexturesを呼び出すたびに新しいテクスチャを生成していると仮定すると、glTexImage2D生成したすべてのテクスチャを追跡しないと、メモリが浪費され、リークが発生します。glTexImage2D入力データを受け取り、ビデオ カード メモリに保存します。呼び出す前にバインドするテクスチャ名glTexImage2D- 生成するものglGenTexturesは、ビデオ カード メモリのチャンクへのハンドルです。

テクスチャが大きく、使用するたびにそのコピーを格納するために新しいメモリを割り当てている場合、すぐにメモリ不足になります。解決策はglTexImage2D、アプリケーションの初期化中に 1 回呼び出しglBindTexture、それを使用する場合にのみ呼び出すことです。クリックしたときにテクスチャ自体を変更したい場合は、 と のみを呼び出しglBindTextureますglTexImage2D。新しい画像が以前の画像と同じサイズである場合はglTexSubImage2D、古い画像データを削除して新しい画像をアップロードする代わりに、古い画像データを上書きするように OpenGL に指示するために呼び出すことができます。

アップデート

あなたの新しいコードに応えて、より具体的な回答で回答を更新しています。OpenGL テクスチャを完全に間違った方法で扱っています。 の出力は であり、またはでglGenTexturesGLuint[]ありません。で生成するすべてのテクスチャに対して、OpenGL はテクスチャへのハンドルを (符号なし整数として) 返します。このハンドルは、指定した状態と、でデータを指定した場合にグラフィック カード上のメモリのチャンクを格納します。ハンドルを保存し、更新したいときに新しいデータを送信するのはあなた次第です。ハンドルを上書きしたり忘れたりすると、データはグラフィックス カードに残りますが、アクセスできなくなります。また、必要なテクスチャが 1 つだけの場合でも、OpenGL に 3 つのテクスチャを生成するように指示しています。Stringchar[]glGenTexturesglTexParameteriglTexImage[1/2/3]D

texture_data固定サイズのまま見ると、 のglTexSubImage2D代わりに でテクスチャを更新できますglTexImage2D。この問題によるメモリ リークを回避するために変更されたコードを次に示します。

texture_data = new GLubyte[width*height]();
GLuint texname; //handle to a texture
glGenTextures(1, &texname); //Gen a new texture and store the handle in texname

//These settings stick with the texture that's bound. You only need to set them
//once.
glBindTexture(GL_TEXTURE_2D, texname);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

//allocate memory on the graphics card for the texture. It's fine if
//texture_data doesn't have any data in it, the texture will just appear black
//until you update it.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
    GL_UNSIGNED_BYTE, texture_data);

...

//bind the texture again when you want to update it.
glBindTexture(GL_TEXTURE_2D, texname);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, 0, GL_RGB,
    GL_UNSIGNED_BYTE, texture_data);

...

//When you're done using the texture, delete it. This will set texname to 0 and
//delete all of the graphics card memory associated with the texture. If you
//don't call this method, the texture will stay in graphics card memory until you
//close the application.
glDeleteTextures(1, &texname);
于 2012-06-26T23:10:46.640 に答える