Nathan Ridley
Nathan Ridley

Reputation: 34396

Why can't I add an int member to my GLSL shader input/output block?

I'm getting an "invalid operation" error when attempting to call glUseProgram against the fragment shader below. The error only occurs when I try to add an int member to the block definition. Note that I am keeping the block definition the same in both the vertex and fragment shaders. I don't even have to access it! Merely adding that field to the vertex and fragment shader copies of the block definition cause the program to fail.

#version 450

...

in VSOutput // and of course "out" in the vertex shader
{
    vec4 color;
    vec4 normal;
    vec2 texCoord;
    //int foo; // uncommenting this line causes "invalid operation"
} vs_output;

I also get the same issue when trying to use free standing in/out variables of the same type, though in those cases, I only get the issue if accessing those variables directly; if I ignore them, I assume the compiler optimizes them away and thus error doesn't occur. It's almost like I'm only allowed to pass around vectors and matrices...

What am I missing here? I haven't been able to find anything in the documentation that would indicate that this should be an issue.

EDIT: padding it out with float[2] to force the int member onto the next 16-byte boundary did not work either.

EDIT: solved, as per the answer below. Turns out I could have figured this out much more quickly if I'd checked the shader program's info log. Here's my code to do that:

bool checkProgramLinkStatus(GLuint programId)
{
    auto log = logger("Shaders");

    GLint status;
    glGetProgramiv(programId, GL_LINK_STATUS, &status);
    if(status == GL_TRUE)
    {
        log << "Program link successful." << endlog;
        return true;
    }
    return false;
}

bool checkProgramInfoLog(GLuint programId)
{
    auto log = logger("Shaders");

    GLint infoLogLength;
    glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLogLength);
    GLchar* strInfoLog = new GLchar[infoLogLength + 1];
    glGetProgramInfoLog(programId, infoLogLength, NULL, strInfoLog);
    if(infoLogLength == 0)
    {
        log << "No error message was provided" << endlog;
    }
    else
    {
        log << "Program link error: " << std::string(strInfoLog) << endlog;
    }

    return false;
}

Upvotes: 4

Views: 3701

Answers (1)

derhass
derhass

Reputation: 45322

(As already pointed out in the comments): The GL will never interpolate integer types. To quote the GLSL spec (Version 4.5) section 4.3.4 "input variables":

Fragment shader inputs that are signed or unsigned integers, integer vectors, or any double-precision floating-point type must be qualified with the interpolation qualifier flat.

This of couse also applies to the corresponding outputs in the previous stage.

Upvotes: 4

Related Questions