Home > OS >  Can a VAO name be re-used after calling glDeleteVertexArrays by calling glGenVertexArrays later?
Can a VAO name be re-used after calling glDeleteVertexArrays by calling glGenVertexArrays later?

Time:02-24

It is my understanding from the OpenGL documentation that a VAO can be deleted (glDeleteVertexArrays), and then later regenerated (glGenVertexArrays). However, I have an issue when I am getting an OpenGL error when trying to re-use an existing VAO variable in a Chunk class (for a Minecraft clone). This only happens for some chunks and I cannot understand why. I output the VAO value (unsigned int type) and it doesn't seem to change after deleting with glDeleteVertexArrays. It was my understanding from the documentation that this value would be reset to zero after running this function. See Chunk class code below.

void Chunk::load()
{
    // Update chunk state
    loaded = true;

    // Set up OpenGL buffers
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &vertexVBO);
    glGenBuffers(1, &textureVBO);
    glGenBuffers(1, &EBO);
    
    // VAO bound before setting up buffer data
    glBindVertexArray(VAO);
    // Indices
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 
                 indices.size() * sizeof(unsigned int), 
                 &indices[0], 
                 GL_DYNAMIC_DRAW);
    // Vertices
    glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
    glBufferData(GL_ARRAY_BUFFER, 
                 vertices.size() * sizeof(float), 
                 &vertices[0], 
                 GL_DYNAMIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(unsigned int), (void*)0);
    glEnableVertexAttribArray(0);
    // Texture Coordinates
    glBindBuffer(GL_ARRAY_BUFFER, textureVBO);
    glBufferData(GL_ARRAY_BUFFER, 
                 texCoords.size() * sizeof(float), 
                 &texCoords[0], 
                 GL_DYNAMIC_DRAW);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(1);
    
    // Unbind
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}
void Chunk::unload()
{
    // Update chunk state
    loaded = false;

    // Delete arrays/buffers.
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &vertexVBO);
    glDeleteBuffers(1, &textureVBO);
    glDeleteBuffers(1, &EBO);
}

CodePudding user response:

Just as delete ptr; in C or free(ptr); in C does not actually change the pointer value of ptr variable, calling glDelete* on an OpenGL object does not change the value of the variables you give it. It is up to you to not use the variable again or to assign it to a neutral value.

That having been said, if your intent is to immediately create a new VAO... why bother? Just clear out the old one by disabling all of the attribute arrays and buffer bindings, and its ready to be used anew:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

GLint maxAttrib;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrib);

for(int attribIx = 0; attribIx < maxAttrib;   attribIx)
{
  glDisableVertexAttribArray(attribIx);
  glVertexAttribPointer(attribIx, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
  glVertexAttribDivisor(attribIx, 0);
}
  • Related