Reputation: 34396
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
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