I’ve been trying out LearnOpenGL’s “Lighting maps” tutorial on diffuse maps and specular maps, and the source involves putting sampler2D’s in a struct in a fragment shader to access the diffuse and specular map texture objects created/used in the tutorial. When I wrote my fragment shader code and tried to compile it in my program with glShaderSource and glCompileShader, I got an error from a glGetShaderInfoLog call saying that “samplers cannot be structure or block members”. Here’s what my fragment shader source looks like when I rewrote a dummy struct to isolate the error:
ctner.fshader (a fragment shader for the cube container rendered in the ‘Lighting maps’ tutorial)
#version 330 core
...
struct TestStruct {
sampler2D test_sampler;
};
uniform TestStruct test_instance;
...
void (main) {
...
}
And here was the output I got from glGetShaderInfoLog (I used the “f” postfix in my source to make my floats explicit, so I’m okay with the “f” warnings):
WARNING: 0:29: Only GLSL version > 110 allows postfix “F” or “f” for float
WARNING: 0:30: Only GLSL version > 110 allows postfix “F” or “f” for float
ERROR: 0:37: ‘structure’ : samplers cannot be structure or block members
WARNING: 0:59: Only GLSL version > 110 allows postfix “F” or “f” for float
WARNING: 0:67: Only GLSL version > 110 allows postfix “F” or “f” for float
WARNING: 0:71: Only GLSL version > 110 allows postfix “F” or “f” for float
This result came from running my program using a Intel HD Graphics 4000 graphics card (glGetString(GL_VENDOR) -> “Intel”, glGetString(GL_RENDERER) -> “Intel® HD Graphics 4000”). My laptop has switchable graphics, and when I ran my program on the AMD card I had (GL_VENDOR -> “ATI Technologies Inc.”, GL_RENDERER -> “AMD Radeon HD 7570M/HD 7670M Graphics”, I didn’t get any errors surprisingly.
What is intended behavior of putting a sampler2D in a struct, according to the GLSL 3.30 spec? I’m not sure, considering it breaks on my Intel card and runs on my AMD card. There’s also a comment thread in the “Lighting maps” tutorial started by user Peter, where people mentioned that putting a sampler2D in a struct works on some cards and breaks on others. I read 4.1.7, and it mentions this about samplers:
They can only be declared as function parameters or uniform variables (see section 4.3.5 “Uniform” ). Except for array indexing, structure field selection, and parentheses, samplers are not allowed to be operands in expressions.
I assume since the spec mentions that a sampler2D can be an operand in a structure field selection (only if the struct is uniform, since a sampler can only be a uniform variable, if not a function parameter), it was intended to be allowed inside a struct definition, but since my Intel card explicitly returned an error about not allowing that, I’m thinking I may have interpreted it wrong.