25

The OpenGL docs for glUseProgram claim that calling it with an argument of zero will cause the results of shader execution to be undefined.

However, after a little searching I've seen a couple examples of people using glUseProgram to uninstall the current shader program.

Is this behavior reliable? If not, then what exactly does glUseProgram(0) do?

rel
  • 764
  • 5
  • 18
user11171
  • 3,821
  • 5
  • 26
  • 35

4 Answers4

32

glUseProgram means that the given program object is the current program that will be used for things that use programs (glUniform, rendering commands, etc). 0 is a lot like NULL for OpenGL objects. It represents not an object (for most objects). Therefore, glUseProgram(0) means that no program is current, and therefore no program will be used for things that use programs.

If you attempt to call the glUniform functions when no program is current, they will fail with an error. If you attempt to render when no program is current, one of two things will happen. In OpenGL 3.1+, core profile, you will get undefined behavior, because core OpenGL must render with a program. In compatibility profiles or version 3.0 or less, you will get fixed-function rendering.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • So in other words I should just not call `glUseProgram(0)`? – user11171 Nov 26 '12 at 09:57
  • 8
    @user11171: No. You should call it when you want to not have a program bound. By doing so, you prevent accidentally rendering with a program that wasn't intended (ie: you forgot to call `glUseProgram` with the actual program you want). You would usually call it when you're finished rendering. – Nicol Bolas Nov 26 '12 at 20:03
  • Interestingly enough, on a Jetson AGX, I forgot to put the `glUseProgram()` before attaching/binding a texture & calling the `glDrawArrays()` and yet I did not get any errors. Yet I thought that the `glDrawArrays()` only worked with programs/shaders. Instead I was getting some really weird results ("random" rendering of whatever). – Alexis Wilke Oct 31 '20 at 01:12
5

Contrary to a lot of answers here and elsewhere, glUseProgram(0) does not revert to fixed-function mode. It is not safe to use it this way. You can use it to set the rendering state to an invalid program object, but if it's still bound to this when rendering occurs, the behaviour is undefined.

From the doc:

"If program is zero, then the current rendering state refers to an invalid program object and the results of shader execution are undefined"

Therefore the results are entirely specific to OS, driver and graphics card. In many cases it appears to revert to fixed-function mode, but this is not defined by the spec and should not be relied upon. It could just as easily keep the last shader, render garbage, or cause a segfault (I've seen this happen).

SystemParadox
  • 8,203
  • 5
  • 49
  • 57
  • 6
    glUseProgram(0) is perfectly safe. As that page says, it's not an error to call glUseProgram(0); only to render anything without a program bound. And this only applies to the core profile. – rdb Apr 04 '15 at 12:52
  • This answer is wrong. rdp is right. Calling "glUseProgram(0)" is not a shader execution. If you perform rendering after calling "glUseProgram(0)", THAT is a shader execution! – Tara Apr 19 '16 at 01:25
  • @Dudeson, you are correct. glUseProgram() does not cause shader execution, but as the spec says, it changes the rendering state so that the results of any shader execution (when you later do something to cause it) are undefined – SystemParadox Apr 19 '16 at 16:11
  • @SystemParadox: You just repeated what I said. – Tara Apr 19 '16 at 16:50
  • @Dudeson, I was trying to show that we are in agreement, and that my answer is not wrong. Calling "glUseProgram(0)" will not result in an immediate error, but it is not safe to do because it results in undefined behaviour when rendering occurs. – SystemParadox Apr 20 '16 at 15:07
  • 1
    @SystemParadox: I see. Altough your answer makes it sound like "glUseProgram(0)" is dangerous by itself. – Tara Apr 20 '16 at 22:47
  • By this logic calling `free(ptr)` is not safe: You can use it to delete a pointer, but if the pointer is still deleted (not reallocated) when another use occurs it is undefined behavior ... – Lorah Attkins Feb 06 '21 at 20:22
  • I have edited my answer to avoid the arguments about whether glUseProgram(0) itself is technically safe or not. I respectfully request that people who have downvoted based on this semantic argument please review my changes and reconsider. The fact that you can safely call glUseProgram(0) itself or not is irrelevant - it is unsafe to render in this state, yet the majority of information out there claims that glUseProgram(0) reverts to fixed function mode. This is simply untrue and should not be relied upon. – SystemParadox Feb 11 '21 at 15:37
  • @SystemParadox: "*it is unsafe to render in this state*" It is in a compatibility profile. The compatibility profile allows for fixed-function OpenGL stuff. The documentation you link to is for core OpenGL, where there is no fixed-function stuff. – Nicol Bolas Feb 11 '21 at 15:38
0

It tells OpenGL to use the fixed-function pipeline.

Name
  • 2,037
  • 3
  • 19
  • 28
0

Once you are using glUseProgram(myShader) all subsequent rendering will be done using the shader ID myShader.

If you are calling this each time you have a material change in a modern openGL 3.1+, there is little use of glUseProgram(0).

However, if you are planning to integrate some fixed-function rendering in there, like glVertex3f(..), then glUseProgram(0) will make sure that the last used shader is not active anymore, and it will use the fixed-function pipeline, like glColor3f(...)

Waqar
  • 8,558
  • 4
  • 35
  • 43
  • No, no, no. glUseProgram(0) DOES NOT revert to fixed-function mode. In many systems it does, but this is not defined by the spec and should not be relied upon. – SystemParadox Feb 11 '21 at 15:40