pingul
pingul

Reputation: 3473

OpenGL shader linking error with no error message

I've been trying to figure this one out for a long time, but can't manage to get things to work. I want simply to compile/run my OpenGL program, but my shaders does not link correctly and I get no helpful error message. In one case the error is purely empty, and in the other case it is ??y? for some reason.

To create my program and compile my shaders, I have the following code:

GLuint buildProgram(const char* vertexShaderFile, const char* fragmentShaderFile)
{
    std::string vs = fileContents(vertexShaderFile);
    std::string fs = fileContents(fragmentShaderFile);
    return createProgram(vs.c_str(), fs.c_str());
}

The shaders look like

#version 330
out vec4 out_color; 
void main()
{
    out_color = vec4(0.5, 0.5, 0.5, 0.5);
}

#version 330
in vec4 in_Position;
void main()
{
    gl_Position = in_Position;
}

With

GLuint createProgram(const char* vertexSource, const char* fragmentSource)
{
    GLuint vertexshader = createShader(vertexSource, GL_VERTEX_SHADER);
    GLuint fragmentshader = createShader(fragmentSource, GL_FRAGMENT_SHADER);
    GLuint program = glCreateProgram();

    glAttachShader(program, vertexshader);
    glAttachShader(program, fragmentshader);

    glLinkProgram(program);
    GLint ret;
    checkShader(vertexshader, GL_LINK_STATUS, &ret, "unable to link vertex shader");
    checkShader(fragmentshader, GL_LINK_STATUS, &ret, "unable to link fragment shader");

    glUseProgram(program);
    return program;
}

GLuint createShader(const char* source, GLenum shaderType)
{
    GLuint shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, &source, NULL);
    glCompileShader(shader);
    GLint isCompiled = 0;
    checkShader(shader, GL_COMPILE_STATUS, &isCompiled, "shader failed to compile");
    if (isCompiled == GL_FALSE)
    {
        glDeleteShader(shader);
        return 0;
    }
    return shader;
}

I try to generate error messages from the shaders by

void checkShader(GLuint shader, GLuint type, GLint* ret, const char* onfail)
{
    switch(type) {
        case(GL_COMPILE_STATUS):
        glGetShaderiv(shader, type, ret);
        if(*ret == false) {
            int infologLength = 0;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
            GLchar buffer[infologLength];
            GLsizei charsWritten = 0;
            std::cout << onfail << std::endl;
            glGetShaderInfoLog(shader, infologLength, &charsWritten, buffer);
            std::cout << buffer << std::endl;
        }
        break;
    case(GL_LINK_STATUS):
        glGetProgramiv(shader, type, ret);
        if(*ret == false) {
            int infologLength =  0;
            glGetProgramiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
            GLchar buffer[infologLength];
            GLsizei charsWritten = 0;
            std::cout << onfail << std::endl;
            glGetProgramInfoLog(shader, infologLength, &charsWritten, buffer);
            std::cout << buffer << std::endl;
        }
        break;
    default:
        break;
    };
}

Running GLuint program = buildProgram("shaders/test.vert", "shaders/test.frag"); gives me the following output:

unable to link vertex shader

unable to link fragment shader

??y?

error build program error 502 : GL_INVALID_OPERATION

Does anyone have a guess why my shaders compile just fine but does not link?

Upvotes: 1

Views: 2814

Answers (1)

derhass
derhass

Reputation: 45362

You are calling getProgramiv(...,GL_LINK_STATUS,...) on shader objects. It doesn't make the slightest sense to even call that checkShader function twice - once for each shader object - when you try to get information about the program (of which there is only one). And it also doesn't make sense to name the function that way, for the GL_LINK_STATUS case.

Upvotes: 6

Related Questions