VertexArrayObject actually change vertex attrib array state.

I have this method in my GraphicDevice class.

void GraphicDevice::enableVertexAttribs(GLuint numVertexAttrib)
{
    const GLuint currNumAttrib(state_.activeVertexesAttribs_);
    if (currNumAttrib > numVertexAttrib)
    {
        for (GLuint i = numVertexAttrib; i < currNumAttrib; ++i)
        {
            glDisableVertexAttribArray(i);
        }
    } else if (currNumAttrib < numVertexAttrib)
    {
        for (GLuint i = 0; i < numVertexAttrib; ++i)
        {
            glEnableVertexAttribArray(i);
        }
    }
    state_.activeVertexesAttribs_ = numVertexAttrib;
}

The class save the current state of openGl and try to minimize the number of gl call.
When used with vertexArrayObject the state became a mess. It’s like vertexArrayObject changes the state of the openGl

In my code i’m doing:

glBindVertexArray(vao1)
...
enableVertexAttribs(3)
...
glBindVertexArray(0)


glBindVertexArray(vao2)
...
enableVertexAttribs(1); // this one will only disable vertexAttrib 2 and 1 because the class thinks that vertexAttrib 0 is already enabled
...
glBindVertexArray(0)

the geometry that I draw with vao2 is invisible and when I capture the the frame with a debuger (nVidia nSight) it say the all attribute are disabled. :frowning:
Seems that vao also change the current bound buffers.
It’s the correct behaviour?

I’m using nVidia driver 326.19

It’s not entirely clear what you’re trying to do, what you expect, or what you get.

The point of VAOs is to encapsulate all vertex array state in an object, so that you can change all of the related state with a single glBindVertexArray() call. This includes the enabled/disabled state of each attribute array (glEnableVertexAttribArray, glDisableVertexAttribArray), so you shouldn’t normally need to enable/disable individual attribute arrays once the VAO has been initialised; you just change between VAOs.

A complete list of the state which is stored in a VAO can be found in the “state tables” section of the OpenGL specification (the section number and the numbers of the relevant tables change between versions, but the state tables are invariably the last numbered section before the appendices).

Thanks, I found the part of the specs that I was looking for. :slight_smile:

I’m building a layer over OGL. In my code I have a more abstract object (batch, effect, material and so on).

I store the state of OGL state to minimize the number of OGL calls. For example:

void GraphicDevice::activateEffect(const EffectPtr effect)
{
    GLuint programName = effect->getProgramNameHandle();
    if (state_.currentProgram_ != programName)
    {
        glUseProgram(programName);
        state_.currentProgram_ = programName;
    }
}

Hoping that glUseProgram is the only function that change the current used program.
This is also useful for stats, for example check how many time I switch program/buffer/textures…

Reading the specs again after your comment I found this.

The currently bound vertex array object is used for all commands which modify vertex array state, such as VertexAttribPointer and EnableVertexAttribArray; all commands which draw from vertex arrays, such as DrawArrays and DrawElements; and all queries of vertex array state

and now I know how to fix my bug, I’ll save vertex binging state only when no VAO is enabled.