c - glUniformMatrix4fv - 无效操作

标签 c opengl opengl-4

<分区>

上下文:

  • OpenGL C API 4.1(“现代”opengl)

问题:

我遇到了一个INVALID OPERATION 以错误的方式使用多个着色器绑定(bind)制服:

// 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);
}

这是从 glGetError 获取错误代码并打印含义的 check_gl_error() 函数:

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);
}

这是两个着色器:

着色器 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);
}

shader2

#version 410
in vec3 position;

uniform mat4 mvp;

void main() {
  gl_Position = mvp * vec4(position, 1.0);
}

实际上,只渲染了网格 2。

我已经打印了 shader1_program.idshader2_program.id,它们是有效的并且具有不同的值,这没问题。

我打印了uniform1uniform2,它们有相同的数值。


申报和绑定(bind)制服的顺序是否正确?

最佳答案

shader1_program.id is the result of the compiled shader1 code from the glCompileShader function. shader2_program.id is the result of the compiled shader2 code from the glCompileShader function.
– Alrick 12 hours ago

那么问题来了。 glUseProgram 需要一个程序对象,而不是一个着色器对象

您可以通过调用 glCreateProgram 创建程序对象,然后使用 glAttachShader 附加已编译的着色器阶段,然后调用 glLinkProgram。您不能直接在着色器上调用 glUseProgram

关于c - glUniformMatrix4fv - 无效操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56308406/

相关文章:

c - 如何从 dll 访问调用应用程序中的变量?

c - 如何为我的 native (C、C++)代码生成序列图?

c++ - 警告 : Variable cannot be bound (it either doesn't exist or has been optimized away)

c++ - OpenGL Planet Generation - 简单矩阵问题(Planet "Spins"With Mouse)

c++ - 布局位置或统一变量中的opengl差异设置值

代码在 C 中未按预期工作

c++ - OpenMP 更新结构的最快方法

iphone - 如何在没有 .nib 文件的情况下创建 opengl iPhone 应用程序?

c++ - GLM 角度轴错误?

macos - 将 IOSurface 支持的纹理转换为 GL_TEXTURE_2D