I'm new to OpenGL. There is a class Mesh, in which there are sub-meshes (meshbuffers). When I draw 1 object, everything is in order. Began to check the program for a memory leak. In the main loop, I delete model No. 1, load model No.2, then in another iteration, vice versa, and so on.

Here so I load models

int mbc = mesh->getMeshBufferCount(); for( int i = 0; i < mbc; ++i ){ GLuint id = 0; glGenVertexArrays( 1, &id ); this->vertexarrayID.push_back( id ); glGenBuffers( 1, &id ); glBindBuffer( GL_ARRAY_BUFFER, id ); this->vertexBuffer.push_back( id ); glBufferData( GL_ARRAY_BUFFER, (( mesh->getMeshBuffer( i )->verticies.size() * 3 ) * sizeof( float )), mesh->getMeshBuffer( i )->verticies.data(), GL_STATIC_DRAW ); glGenBuffers( 1, &id ); glBindBuffer( GL_ARRAY_BUFFER, id ); this->uvBuffer.push_back( id ); glBufferData( GL_ARRAY_BUFFER, (( mesh->getMeshBuffer( i )->tcoords.size() * 2 ) * sizeof( float )), mesh->getMeshBuffer( i )->tcoords.data(), GL_STATIC_DRAW ); glGenBuffers( 1, &id ); glBindBuffer( GL_ARRAY_BUFFER, id ); this->normalBuffer.push_back( id ); glBufferData( GL_ARRAY_BUFFER, (( mesh->getMeshBuffer( i )->normals.size() * 3 ) * sizeof( float )), mesh->getMeshBuffer( i )->normals.data(), GL_STATIC_DRAW ); glGenBuffers( 1, &id ); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id ); this->elementBuffer.push_back( id ); glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh->getMeshBuffer( i )->indices.size() * sizeof(unsigned int), mesh->getMeshBuffer( i )->indices.data() , GL_STATIC_DRAW); } 

When I documented the call to the render () function there is no leakage, it means the problem is in drawing.

 int mbcount = mesh->getMeshBufferCount(); for( int i = 0; i < mbcount; ++i ){ glLoadIdentity(); glBindVertexArray( this->vertexarrayID[ i ] ); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer[ i ] ); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, this->uvBuffer[ i ] ); glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,(void*)0); glEnableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, this->normalBuffer[ i ] ); glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0,(void*)0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->elementBuffer[ i ]); glDrawElements(GL_TRIANGLES,mb->indices.size(),GL_UNSIGNED_INT,(void*)0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); } 

I do not understand how to do it right. 2 models, a car and a plane, in each iteration one is deleted, the other is created, if you enable rendering, they are drawn but the memory increases.


The problem was the removal of the VAO. Before deleting put glBindVertexArray

  glBindVertexArray( this->vertexarrayID[ i ] ); glDeleteVertexArrays( 1, &vertexarrayID[ i ] ); 

    1 answer 1

    I do not understand how to do it right. 2 models, a car and a plane, in each iteration one is deleted, the other is created, if you enable rendering, they are drawn but the memory increases.

    Let's start with the fact that the models are not removed individually but all at once, because when cleaning the buffers, the colors and depths are glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); everything that has been drawn is erased and rendered again in the next frame.

    Secondly, when rendering, it will be correct to bind not vbo (vertex buffer object) but vao (vertex array object) - that is, instead of

     glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer[ i ] ); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0); //... 

    you need something like

     glBindVertexArray(this->vertexarrayID[ i ]); glDraw... glBindVertexArray(0); 

    And you vbo bind vbo and configure vertex attribute reading only once before rendering, when loading the model, otherwise it makes no sense to use vao , which eliminates duplicate operations in the rendering cycle, in other words, this piece of code

     glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer[ i ] ); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, this->uvBuffer[ i ] ); glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,(void*)0); glEnableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, this->normalBuffer[ i ] ); glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0,(void*)0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->elementBuffer[ i ]); 

    put it in the place where your model loads.

    And since we are talking about correctness - do not use functions from the outdated opengl API , I’m glLoadIdentit() about glLoadIdentit() - there are a bunch of math libraries sharpened by opengl .

    Finally, regarding memory leaks - delete each buffer through

     glDeleteBuffers(1, &this->vertexBuffer[ i ]); glDeleteBuffers(1, &this->vertexarrayID[ i ]); 
    • In the examples, www.opengl-tutorial.org noticed that glGenVertexArrays( 1, &id ); was removed glGenVertexArrays( 1, &id ); and glBindVertexArray( this->vertexarrayID[ i ] ); I removed these lines, drawing stopped. Like a memory leak. As I understand you need to do the right VBO. - user185136
    • @ArtemRachmaninov you need to read about vbo and vao - ampawd