Search code examples
c++openglvbovao

I think this open gl code is causing a memory leak, What mistake am I making?


In this code I attempt to draw two lines, initially it's basically a short setup of a VBO and a VAO and then I draw the line, it seems to work, but when I copy and paste the code a few times to get more lines I seem to be creating a memory leak, and therefore must be doing it wrong.

I have a feeling there's a better way to do it, such as create a VAO in an initialization function elsewhere that only runs once and reuse it delete my buffer objects, So I just bind the VAO and draw or something in my draw function. So I tried to do it all in this function first with an if x = 0 make the VBO and VBO etc. then x=1 so it only runs once for the creationof buffer objects etc. But then I get errors and nothing draws saying there's no bound VAO ... I know that the rules for destroying different data types are kinda complicated and maybe I'm not clear on them.

It draws nicely, but as I say the memory keeps going up about 1 megabyte per second. This seems to occur after about a minute running.

        void drawMenu(){
    vec3 start(-3,-.8,0);
    vec3 end(3,-.8,0);
    startPoint = start;
    endPoint = end;
    GLfloat colorToSet[4]= {1.0f,1.0f,1.0f,1.0f};
    
    verticesl = {
    start.x, start.y, start.z,
    end.x, end.y, end.z,
    };
        
            
    glUseProgram(shaderProgram);
        
    GLuint uniformLocation = glGetUniformLocation(shaderProgram,"uniformColor");
    if (uniformLocation<0){
    cout<< "drawline function can't find a uniform location in your fragment shader "<< endl;
        }
    else glUniform4f(uniformLocation, colorToSet[0],colorToSet[1],colorToSet[2],colorToSet[3]);
    
    glGenBuffers(1, &VBO);
     
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticesl), verticesl.data(), GL_STATIC_DRAW);
    glGenVertexArrays(1, &VAO);// can creat the VAO now to store the VBO in
            
    glBindVertexArray(VAO);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
          
          
            
    glLineWidth(4.0f);
            
    glDrawArrays(GL_LINES, 0, 2);
    glDeleteBuffers(1,&VBO);
        
    GLfloat colorToSet1[4]= {1.0f,1.0f,1.0f,1.0f};
         
    
    start = vec3(-3,-.9,0);
    end = vec3(3,-.9,0);
    glUniform4f(uniformLocation, colorToSet1[0],colorToSet1[1],colorToSet1[2],colorToSet1[3]);
            
    verticesl = {
    start.x, start.y, start.z,
    end.x, end.y, end.z,
    
    };
           
    glGenBuffers(1, &VBO);
      
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticesl), verticesl.data(), GL_STATIC_DRAW);//fills the previously bound vbo
           
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind the buffer
          
          
             
    glLineWidth(4.0f);
             
    glDrawArrays(GL_LINES, 0, 2);
            
    glDeleteBuffers(1,&VBO);
              
               
          
           
} 

Solution

  • You are doing glGenBuffers and glBufferData inside a render function, which will allocate GPU memory and loads it every frame. Instead, use glGenBuffers in the setup part of your program. Most likely you are only changing the transformation which is supplied to the shader for most rendering (meshes, terrain, etc), so you only need to call glBufferData once in the setup. If you really are changing vertex data every frame (dynamic text? animated constructed meshes?), then you will need to use GL_DYNAMIC_DRAW, when defining your buffers, then you can glBufferData inside render function sparingly.