Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must I "use" a shader program before I can set its uniforms?

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.

like image 644
Rob Avatar asked Feb 05 '23 01:02

Rob


1 Answers

You don't have to. GL 4.1 and above gives you glProgramUniform(), which takes the program object you want to modify.

like image 143
Nicol Bolas Avatar answered Mar 05 '23 23:03

Nicol Bolas