I'm trying to wrap my head around the relation between a GL "program", and the VAOs, buffers, textures, etc. I don't quite understand when I need to "use" my shader program, and when (if ever) I need to "un-use" it?

So when do I need to use the shader program (i.e. invoke glUseProgram), exactly? Does my shader program need to be in "use" when:

  1. Creating and binding VAOs?
  2. Creating and binding VBOs?
  3. Buffering data to VBOs?
  4. Defining vertex attributes (i.e. invoking glVertexAttribPointer)?

Your shader is only used during rendering, so it only needs to be enabled before you render the objects.

You also don't need to disable it, there won't be any problems if a shader stays enabled.

  • \$\begingroup\$ Are you sure about this? What about compiling/linking the vertex and fragment shaders? I'm fairly certain the target program needs to be "used" before this step. But honestly, I'm not sure \$\endgroup\$ – gromit190 Oct 30 '17 at 10:19
  • \$\begingroup\$ Also, some quick testing now reveals that when defining vertex attributes with the wrong program in use makes the vertex attributes incorrect... \$\endgroup\$ – gromit190 Oct 30 '17 at 10:29
  • \$\begingroup\$ @gromit190 What makes you think that? A program is useless before you add the shaders to it and you need to compile the shaders before adding them to the program. Again, shaders only need to be enabled when you render using them and when \$\endgroup\$ – Bálint Oct 30 '17 at 10:30
  • \$\begingroup\$ @gromit190 - I suggest you read the GL spec and documentation, it's quite clear on which operations depend on the current program and which don't. \$\endgroup\$ – Maximus Minimus Oct 30 '17 at 11:34
  • \$\begingroup\$ @Bálint Sorry, I have been looking more into the problems and must correct myself. Thanks for sharing your knowledge :-) \$\endgroup\$ – gromit190 Oct 30 '17 at 16:48

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:

  1. Vertex rendering commands, which use the currently bound program for rendering operations.
  2. 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.


You need to enable your shader before rendering and disable it when you don't need it anymore. If you are going to want to change uniforms in your shader at runtime for example, you are going to want to enable your shader in the main game loop, and then change the uniforms.

Disabling the shader is not required, but it would be better if you do it.

  • 1
    \$\begingroup\$ I disagree that it's better to disable shaders (or otherwise unbind), doing so just hides other errors in your program. \$\endgroup\$ – Maximus Minimus Oct 31 '17 at 8:33
  • 1
    \$\begingroup\$ You should unbind the shader after closing the program. Although this is not actually required in order to make the program work, i like to do it \$\endgroup\$ – user100681 Oct 31 '17 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.