The following glsl code appears in my fragment shader. The struct definition causes no problems, but my attempt to use it as the type of a uniform array causes an "invalid operation" error, which is not particularly helpful.
struct InstanceData
{
vec3 rotation;
vec3 scale;
mat4 position;
};
layout (std140) uniform InstanceData instances[100];
How do I structure this code correctly so that it compiles without error, and is thus ready for me to populate with data? Note that I am using core profile version 4.5.
Edit: It seems to be something to do with the use of layout (std140)
. Removal of that part allows the code to compile, though don't I need that to ensure that the glsl compiler packs the struct data in a predictable way?
Edit: Still not working. My entire vertex shader code looks like this:
#version 450
layout(location=0) in vec4 in_Position;
layout(location=1) in vec4 in_Color;
out vec4 ex_Color;
flat out int ex_Instance;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
// ------ preliminary addition of uniform block to be used soon ------
struct layout (std140) InstanceData
{
vec3 rotation;
vec3 scale;
mat4 position;
};
layout (std140, binding = 0) uniform InstanceData
{
InstanceData instances[100];
};
// -------------------------------------------------------------------
void main(void)
{
gl_Position = (projectionMatrix * viewMatrix * modelMatrix) * in_Position;
ex_Color = in_Color;
}
Note that I haven't written any code externally to populate the uniform buffer yet, nor, as you can see above, have I adjusted my code to make use of the data either. I just want it to compile and work initially as-is (i.e. declared but not used), at which point I will add additional code to start making use of it. There's no point going even that far if the program doesn't like the declaration to begin with.
Edit: Finally figured out the problem by using the shader info log, like so:
GLint infoLogLength;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &infoLogLength);
GLchar* strInfoLog = new GLchar[infoLogLength + 1];
glGetShaderInfoLog(id, infoLogLength, NULL, strInfoLog);
In a nutshell, as Anton said, I was using layout
incorrectly, and my uniform block had the same name as my struct, creating all kinds of confusion for the compiler.