I am encoutering an INVALID OPERATION binding uniforms the wrong way with multiple shaders :
// Getting ids for each uniform
GLuint uniform1 = glGetUniformLocation(shader1_program.id, "mvp");
GLuint uniform2 = glGetUniformLocation(shader2_program.id, "mvp");
loop {
// Print mesh 1 shader 1
glUseProgram(shader1_program.id);
glUniformMatrix4fv(uniform1 , 1, GL_FALSE, mvp1);
check_gl_error(); // =============================> this one provides the error
glBindVertexArray(vao1);
glDrawArrays(GL_TRIANGLES, 0, vertex_number1);
// Print mesh 2 with shader2
glUseProgram(shader2_program.id);
glUniformMatrix4fv(uniform2 , 1, GL_FALSE, mvp2);
check_gl_error();
glBindVertexArray(vao2);
glDrawArrays(GL_TRIANGLES, 0, vertex_number2);
}
Here is the check_gl_error()
function that get error code from glGetError
and print signification:
typedef struct glmaperror_s {
GLenum err;
char *string_error;
} glmaperror_t;
static const glmaperror_t glmaperror[] = {
{ GL_INVALID_OPERATION, "GL_INVALID_OPERATION", },
{ GL_INVALID_ENUM, "GL_INVALID_ENUM", },
{ GL_INVALID_VALUE, "GL_INVALID_VALUE", },
{ GL_OUT_OF_MEMORY, "GL_OUT_OF_MEMORY", },
{ GL_INVALID_FRAMEBUFFER_OPERATION, "GL_INVALID_FRAMEBUFFER_OPERATION", },
};
int check_gl_error(void)
{
GLenum err;
char *error;
error = 0;
while ((err = glGetError()) != GL_NO_ERROR) {
error = "Unhandled GL error";
for (size_t i = 0; i * sizeof(glmaperror_t) < sizeof(glmaperror); i++) {
if (glmaperror[i].err == err) {
error = glmaperror[i].string_error;
}
}
fprintf(stderr, "[GL Error]: %s\n", error);
return (-1);
}
return (0);
}
Here are the two shaders :
shader1 :
#version 410
in vec3 position;
in vec3 color;
out vec4 _color;
uniform mat4 mvp;
void main() {
gl_Position = mvp * vec4(position, 1.0);
_color = vec4(color, 255.0);
}
shader2
#version 410
in vec3 position;
uniform mat4 mvp;
void main() {
gl_Position = mvp * vec4(position, 1.0);
}
Actually, only mesh 2 is rendered.
I have printed shader1_program.id
and shader2_program.id
, they are valid and have different values which is ok.
I have printed uniform1
and uniform2
, they have the same numerical value.
Is it the right order to declare and bind uniform ?
shader1_program.id
is the result of the compiled shader1 code from theglCompileShader
function.shader2_program.id
is the result of the compiled shader2 code from theglCompileShader
function.
– Alrick 12 hours ago
So that's the problem then. glUseProgram
expects a program object, not a shader object.
You create program objects by a call to glCreateProgram
, followed by attaching your compiled shader stages with glAttachShader
, and then calling glLinkProgram
afterwards. You cannot call glUseProgram
on a shader directly.