I am using OpenGL 4.5 in C++ and GLSL 410.
I came across a problem recently where I was attempting to set a shader program's uniform variable without first using the shader program with glUseProgram
. I had a fragment shader with a uniform variable called input_color
(a vec4 which I would set the output color to) attached to my shader_program
. Please note I do call glUseProgram(shader_program)
in my main draw loop before drawing anything that should use it.
// set uniforms
GLint input_color = glGetUniformLocation(shader_program, "input_color");
glUniform4f(input_color, 0.5f, 0.3f, 0.2f, 1.0f);
A triangle drawn with this program was all black, not the result I was expecting. After some experimenting, I realized I needed to use the program before setting its uniforms.
// set uniforms
glUseProgram(shader_program); // my change
GLint input_color = glGetUniformLocation(shader_program, "input_color");
glUniform4f(input_color, 0.5f, 0.3f, 0.2f, 1.0f);
Drawing results in a triangle of the correct color.
My question is why did I need to start using the program first? I understand that OpenGL works as a state machine, but in this instance why is the current shader program state necessary? After all, I explicitly pass the shader_program
index as a parameter to glGetUniformLocation
in order to get input_color
's memory index.
I'm hoping the answer to this will help me understand states in OpenGL better, and how blocks of memory representing shader programs on the GPU are utilized or managed.