I try to use attribute variable as an index to array in uniform buffer object. While linking the program I get linking error, but unfortunately there is no additional error descriptions. If I change a_Index
to constant in vertex shader, everything works fine.
Help me please)) What is wrong here?
This is my vertex shader:
#version 430
layout(location = 0) in vec2 a_Position;
layout(location = 1) in int a_Index;
struct Node {
mat4 model; // 0 (column 0)
// 16 (column 1)
// 32 (column 2)
// 48 (column 3)
vec4 color; // 64
float depth; // 68
float type; // 72
};
layout(std140, row_major) uniform LinesBuffer {
Node nodes[];
};
out vec4 v_vertex_Color;
out float v_vertex_Depth;
uniform mat4 u_Projection;
uniform mat4 u_View;
uniform mat4 u_Model;
void main()
{
Node node = nodes[a_Index];
if (node.type == 0.0)
{
return;
}
v_vertex_Color = node.color;
v_vertex_Depth = node.depth;
gl_Position = u_Projection * u_View * u_Model * node.model * vec4(a_Position, 0.0, 1.0);
}
Fragment shader:
#version 430
in vec4 v_vertex_Color;
in float v_vertex_Depth;
layout(location = 0) out vec4 color;
void main()
{
gl_FragDepth = v_vertex_Depth;
color = v_vertex_Color;
}
The code that is used to fetch error message (logLen
equals to zero):
int logLen;
glGetProgramiv(this->glId, GL_INFO_LOG_LENGTH, &logLen);
if (logLen > 0)
{
char* log = new char[logLen];
int written;
glGetProgramInfoLog(this->glId, logLen, &written, log);
fprintf(stderr, "Program log: \n%s", log);
delete[] log;
}
See OpenGL Shading Language 4.60 Specification (HTML) - 4.1.9. Arrays
[...] Except for the last declared member of a shader storage block [...], the size of an array must be declared (explicitly sized) before it is indexed with anything other than a constant integral expression. [...]
Note, "with anything other than a constant integral expression." is exactly what you do (nodes[a_Index]
instead of nodes[0]
).
So you have 2 options:
declare the size of the array.
use a Shader Storage Block instead of a Uniform Block. e.g.:
layout(std140, row_major) buffer LinesBuffer {
Node nodes[];
};