質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.77%

C++ OpenGL メモリリーク 原因がわかりません

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 195

score 9

C++/OpenGLを使ってゲームを作っています。
同じコードでMac、Windows両方動くので両方でメモリリークを確認しました。

MacのXCodeでメモリリークの原因を探ってみたのですが、
どうやら自分の描いたコードで直接的な原因では無いようで、どこでメモリリークが発生しているのか
わかりません。(newでdeleteしてないなどの直接的な原因ではない、OpenGLの関数で開放し忘れている)

このSquareShapeクラスを使っている場所でSquareShapeクラスを
newで6つ使っています。

素人なのでコードがわかりづらい、文字制限で載せられないですがよろしくお願いします。
必要な情報が足らないようでしたら補足します。

試したこと

このSquareShapeクラスを6つ使っている場所で5つをコメントアウトし、
一つだけnewで使うとメモリリークは無くなります。
ですが2つ以上newするとメモリリークが発生します。
作ったオブジェクトはすべてdeleteしています。

補足情報(FW/ツールのバージョンなど)

OpenGL 3.2
メモリリークはしていますが動きます。

//SquareShapeクラス,public Textureクラス継承

SquareShape::SquareShape(Frame f)
: location { 0.0, 0.0 }, fLocation { 0.0, 0.0 }, alpha{0.0, 0.0, 0.0, 0.0}, texureBindFrag(false) , frame(f.size, f.position)  { this->program = loadProgram("object.vert", "object.frag"); }

SquareShape::SquareShape(GLdouble width, GLdouble height, GLdouble x, GLdouble y)
: location { 0.0, 0.0 }, fLocation { 0.0, 0.0 }, alpha{0.0, 0.0, 0.0, 0.0}, texureBindFrag(false), frame(width, height, x, y) { this->program = loadProgram("object.vert", "object.frag"); }

SquareShape::SquareShape(Size s, Position p)
: location { 0.0, 0.0 }, fLocation { 0.0, 0.0 }, alpha{0.0, 0.0, 0.0, 0.0}, texureBindFrag(false), frame(s ,p) { this->program = loadProgram("object.vert", "object.frag"); }

SquareShape::SquareShape(Size s, GLdouble x, GLdouble y)
: location { 0.0, 0.0 }, fLocation { 0.0, 0.0 }, alpha{0.0, 0.0, 0.0, 0.0}, texureBindFrag(false), frame(s, x, y) { this->program = loadProgram("object.vert", "object.frag"); }

SquareShape::SquareShape(GLdouble width, GLdouble height, Position p)
: location { 0.0, 0.0 }, fLocation { 0.0, 0.0 }, alpha{0.0, 0.0, 0.0, 0.0}, texureBindFrag(false), frame(width, height, p) { this->program = loadProgram("object.vert", "object.frag"); }

SquareShape::~SquareShape() {
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);
    glDeleteBuffers(1, &uv_vbo);
    glDeleteBuffers(1, &colorVbo);
    glDeleteBuffers(1, &alphaVbo);
    glDeleteProgram(this->program);
}

void SquareShape::setShaderProgram(GLuint program) {
    this->program = program;
}

void SquareShape::createSquare() {
    vertexInit();
    createVbo();
}

void SquareShape::bindVao() {
    glBindVertexArray(vao);
}

void SquareShape::bindVbo() {
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
}

void SquareShape::createVbo() {
    glGenVertexArrays(1, &vao);
    bindVao();

    glGenBuffers(1, &vbo);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof (Vertex), &vertex, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 2, GL_DOUBLE, GL_FALSE, 0, 0);

    // テクスチャのvbo
    //追加:テクスチャのUV座標を格納するためのVBOを作成
    glEnableVertexAttribArray(1);
    glGenBuffers(1, &uv_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, uv_vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_uv), &vertex_uv, GL_STATIC_DRAW);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (char *)0 + sizeof(GLfloat) * 8);

    glEnableVertexAttribArray(2);
    glGenBuffers(1, &colorVbo);
    glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(color), color, GL_STATIC_DRAW);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(3);
    glGenBuffers(1, &alphaVbo);
    glBindBuffer(GL_ARRAY_BUFFER, alphaVbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(alpha), alpha, GL_STATIC_DRAW);
    glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, 0);

    glBindVertexArray(0);
}

void SquareShape::vertexInit()
{
    vertex.lowerLeft.x  = this->frame.position.x; // WINDOW_ASPECT
    vertex.lowerLeft.y  = this->frame.position.y;

    vertex.lowerRight.x = vertex.lowerLeft.x + this->frame.size.width;
    vertex.lowerRight.y = vertex.lowerLeft.y;

    vertex.upperRight.x = vertex.lowerRight.x;
    vertex.upperRight.y = vertex.lowerRight.y + this->frame.size.height;

    vertex.upperLeft.x  = vertex.lowerLeft.x;
    vertex.upperLeft.y  = vertex.upperRight.y;
}

void SquareShape::changeColor(GLfloat red, GLfloat green, GLfloat blue) {
    for(int i = 0; i < 4; i++){
        color[i].red = red;
        color[i].green = green;
        color[i].blue = blue;
    }
        bindVao();

        glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(color), color, GL_STATIC_DRAW);
        glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
}

void SquareShape::changeAlpha(GLfloat alpha) {
    this->alpha[0] = 1.0 - alpha;
    this->alpha[1] = 1.0 - alpha;
    this->alpha[2] = 1.0 - alpha;
    this->alpha[3] = 1.0 - alpha;

    bindVao();

    glBindBuffer(GL_ARRAY_BUFFER, alphaVbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(this->alpha), this->alpha, GL_STATIC_DRAW);
    glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, 0);
}

void SquareShape::setBindTexture(bool set) {
    this->texureBindFrag = set;
}

void SquareShape::draw() {
    glUseProgram(this->program);
    if(this->texureBindFrag) this->bindTexture(0);
    else glBindTexture(GL_TEXTURE_2D, 0);
    bindVao();
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindVertexArray(0);
    glUseProgram(0);
}

const GLfloat* SquareShape::getLocation() const
{
    return fLocation;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

vaoのglDeleteVertexArraysをコメントアウトしたらメモリリークが無くなりました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る