这些不匹配的着色器变量为什么不产生链接器错误?

时间:2019-05-23 03:41:59

标签: opengl glsl shader

在着色器编译和链接期间出现某些故障时,我试图引发异常并中止我的程序。我引入了一个错字:为我的顶点着色器中的输出变量命名与我的片段着色器中的预期输入变量有所不同。我希望这在链接上失败,但是一切正常(片段着色器中变量的值最终为0)。特别地,glGetProgramiv(id, GL_LINK_STATUS, &success);将成功设置为true。发生了什么事?

顶点着色器

#version 330 core
layout (location = 0) in vec3 aPos;
out vec4 vertexColo; // NOTE THE MISSPELLING HERE

void main()
{
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    vertexColo = vec4(1.0 - aPos.y, 0.8 - aPos.y, aPos.x, 1.0);
}

片段着色器

#version 330 core
out vec4 FragColor;

in vec4 vertexColor;

void main()
{
    FragColor = vertexColor;
}

测试代码:

namespace btv {

namespace {
static void test_compile(unsigned id, const char* path)
{
    int success;
    glGetShaderiv(id, GL_COMPILE_STATUS, &success);
    if (!success) {
        constexpr size_t BUF_SIZE = 1024;
        char buf[BUF_SIZE];
        glGetShaderInfoLog(id, BUF_SIZE, NULL, buf);
        std::stringstream ss;
        ss << "Shader at path: " << path << " failed with message: "
            << buf;
        throw std::runtime_error(ss.str());
    }
}

static void test_link(unsigned id, const char* v_path, const char* f_path)
{
    int success;
    glGetProgramiv(id, GL_LINK_STATUS, &success);
    if (!success) {
        constexpr size_t BUF_SIZE = 1024;
        char buf[BUF_SIZE];
        glGetProgramInfoLog(id, BUF_SIZE, NULL, buf);
        std::stringstream ss;
        ss << "Program with v shader: " << v_path << ", f shader: " << f_path
           <<  " failed with message: " << buf;
        throw std::runtime_error(ss.str());
    }
}
}

Program::Program(const char* v_path, const char* f_path)
{
    std::string v_src = slurp(v_path);
    std::string f_src = slurp(f_path);

    const char *v_c = v_src.data();
    const char *f_c = f_src.data();


    unsigned v_shdr = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(v_shdr, 1, &v_c, nullptr);
    glCompileShader(v_shdr);
    test_compile(v_shdr, v_path);


    unsigned f_shdr = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(f_shdr, 1, &f_c, nullptr);
    glCompileShader(f_shdr);
    test_compile(f_shdr, f_path);

    id = glCreateProgram();
    glAttachShader(id, v_shdr);
    glAttachShader(id, f_shdr);
    glLinkProgram(id);
    test_link(id, v_path, f_path);
}
} // namespace btv

1 个答案:

答案 0 :(得分:4)

问题与GLSL版本有关。在OpenGL Shading Language 4.60 Specification(4.3.4输入变量)中,如果静态使用了输入变量,但在上一阶段未声明任何相应的输出变量,则明确指出这是链接时错误。

OpenGL Shading Language 3.30 Specification中缺少规范的这一部分。

将GLSL版本更改为(例如)4.60(>>> sklearn.__version__ '0.19.2' ),您将得到预期的错误。
例如

  

“错误:“ vertexColor”未声明为上一阶段的输出”