7
\$\begingroup\$

Looking at examples at http://learnopengl.com/#!Getting-started/Hello-Triangle and many different places, I've found that the draw sequence usually goes like this:

// setup VBO, VAO, load shaders


while (true) { // game loop
  glUseProgram(shader);
  glBindVertexArray(someVAO);
  drawStuff(...);

  // ...
}

Now my question is, is there any reason why I'd want to repeatedly do glUseProgram(...) on each frame, unless I'm using multiple shaders (such as OpenGL clearing currently used shader after rendering?)?

Also, if I am using multiple shaders, do I need to glUseProgram before switching to a different VAO? I'm unclear on whether the VAO just gets set as active, or if it actually modifies the state of a currently used shader. I've tried looking this up in the OpenGL spec, but couldn't quite find it.

edit: Yes I did mean glUseProgram, sorry.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Note that calling some function once per frame has like zero performance impact. It also just helps make your code have a clear "setup rendering" and "finish rendering" steps in your loop, which will save you pain down the road. \$\endgroup\$ Apr 17 '16 at 18:31
3
\$\begingroup\$

Maybe you mean glUseProgram()? I can't find something related to glUseShader, so if i'm wrong then sorry. But if this is the case then basically you use it when you want to use the shader itself.

This is an example from my current opengl project (EDIT: Oh, by the way, this example code is on the main rendering loop):

GL30.glBindVertexArray(vao); // Binding vao.
majorShader.glUseProgram(); // Don't mind the "majorShader" it's an util class i made.
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); //Don't mind these, some framebuffer stuffs.
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fb);
display.renderTriangle(); // Render the scene.

GL30.glBindVertexArray(screenVao); // Bind a different vao.
screenShader.glUseProgram(); // Switching shader because it does a different thing
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbTex);
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
display.renderScreen(); // Render the frame buffer, which used different vao, vbo and shader.

But, if you're planning on using only one shader, then you can just call glUseProgram() once on initialization function or something like that before drawing.

EDIT2 (Summary): So, 1. I don't see why you need to call glUseProgram() repeatedly if you're only using one shader (Unless maybe you call glUseProgram(0) for some reason and want to use shader again..) 2. You can see in my case, i use glUseProgram() after calling glBindVertexArray() when i want to do a something with a different shader

\$\endgroup\$
5
  • \$\begingroup\$ I do not understand why you need to glUseProgram if you change vao. I always think program as a combination of executables of different stages. So if the shaders stay the same, and the program use the same shaders, why there is a need to call glUseProgram? Another thing I do not understand is that is there any case one need to call glUseProgram(0). Because according to specification, If program is zero, then the current rendering state refers to an invalid program object and the results of shader execution are undefined. However, this is not an error. \$\endgroup\$
    – dudu
    Jan 9 '19 at 5:48
  • \$\begingroup\$ @dudu You are right on the first one, as long as the vao provides all the data the shader need. In this case i'm using a different one, but i'll remove the misleading comment, thank you. As for glUseProgram(0), it is usually used for good practices which is unbind what you bind or when you are working with something like SFML rendering functions which requires you to unbind any program for it to work correctly. \$\endgroup\$
    – Greffin28
    Jan 10 '19 at 8:13
  • \$\begingroup\$ unbinding is quite taxing and the reason to write glBindProgram(0) just for code readability is completely useless in my opinion. It's completely possible to write a rendering architecture without unbinding the currently used glProgram \$\endgroup\$
    – user115399
    Jan 10 '19 at 8:41
  • \$\begingroup\$ In a reasonably efficent rendering framework (that we suppose uses only OpenGL as a rendering Api) unbinding the program is rarely ever done; Unbinding is the same symptom as resetting state right after a drawcall, and indicates an underlying design problem. \$\endgroup\$
    – user115399
    Jan 10 '19 at 8:45
  • \$\begingroup\$ @GabrieleVierti You're absolutely right, it does take a toll on performance. We usually write those only on development or debugging phase and are removed on release build. \$\endgroup\$
    – Greffin28
    Jan 10 '19 at 10:45

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.