我遇到了无效的操作,以错误的方式绑定多个着色器:
// 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);
}
Run Code Online (Sandbox Code Playgroud)
这是check_gl_error()
获取错误代码glGetError
并打印含义的函数:
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);
}
Run Code Online (Sandbox Code Playgroud)
这是两个着色器:
着色器1:
#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);
}
Run Code Online (Sandbox Code Playgroud)
着色器2
#version 410
in vec3 position;
uniform mat4 mvp;
void main() {
gl_Position = mvp * vec4(position, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
实际上,只渲染了网格 2。
我已经打印了shader1_program.id
和shader2_program.id
,它们是有效的并且具有不同的值,这是可以的。
我已经打印了uniform1
和uniform2
,它们具有相同的数值。
声明和绑定制服的顺序正确吗?
\n\n\n\n
shader1_program.id
是该函数编译的shader1代码的结果glCompileShader
。是该函数编译的shader2代码shader2_program.id
的结果。\n \xe2\x80\x93 阿尔里克 12 小时前glCompileShader
那么这就是问题所在。glUseProgram
需要一个程序对象,而不是着色器对象。
您可以通过调用 来创建程序对象glCreateProgram
,然后使用 附加已编译的着色器阶段glAttachShader
,然后glLinkProgram
再调用。您不能glUseProgram
直接调用着色器。