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);
}