Programs have nothing to do with vertex array state. Yes, really.
VAOs and their associated functions govern vertex array state. Those are the objects which decide how to interpret vertex data from buffer objects. VAOs are the objects that govern how this vertex data is packaged into a vertex for use by the vertex shader.
But the VAO and the vertex shader have no direct relationship. The VAO describes how data is fed to vertex attribute indices, and the vertex shader reads data from those attribute indices. But the two objects never directly communicate. They communicate indirectly though the list of attribute indices.
As such, a particular VAO can feed many distinct vertex shaders. So long as the VS's take the same attributes that the VAOs generate, everything is fine. Similarly, the same VS can be fed from multiple distinct VAOs, so long as they're providing the same attributes.
The only things in OpenGL that care about which programs are in use are:
- Vertex rendering commands, which use the currently bound program for rendering operations.
glUniform*
commands, which modify the uniform data in the currently bound program. But you should be using glProgramUniform*
whenever possible, as those don't require the program to be bound to work.
What about compiling/linking the vertex and fragment shaders?
What about it? glCompileShader
takes the shader object as a parameter; it doesn't care about what program is bound through glUseProgram
. Same goes for glLinkProgram
.
Also, some quick testing now reveals that when defining vertex attributes with the wrong program in use makes the vertex attributes incorrect...
That is a bug in your code. You're probably querying attribute indices from the program with glGetAttribLocation
, rather than developing an index convention.