Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

opengl

glsl

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;
}
like image 813
Nathan Ridley Avatar asked Sep 17 '25 16:09

Nathan Ridley


1 Answers

(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.

like image 102
derhass Avatar answered Sep 19 '25 05:09

derhass