OpenGL でテクスチャを使用してメモリを管理するにはどうすればよいでしょうか? 質問する

OpenGL でテクスチャを使用してメモリを管理するにはどうすればよいでしょうか? 質問する

私のアプリケーションでは、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);

クローズリクエストとダウン投票がこれで止まることを願っています!

ベストアンサー1

glGenTexturesを呼び出すたびにで新しいテクスチャを生成していると仮定するとglTexImage2D、メモリを無駄にし、生成したすべてのテクスチャを追跡しないとメモリがリークします。 はglTexImage2D入力データを取得し、ビデオ カード メモリに保存します。 を呼び出す前にバインドするテクスチャ名 (glTexImage2Dで生成するテクスチャ名) は、glGenTexturesビデオ カード メモリのチャンクへのハンドルです。

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

アップデート

新しいコードに応じて、より具体的な回答に私の回答を更新します。OpenGL テクスチャの扱い方が完全に間違っています。 の出力はglGenTexturesであり、や ではGLuint[]ありません。 を使用して生成したテクスチャごとに、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);

おすすめ記事