使用顶点属性变量作为 UBO 数组的索引
Using vertex attribute variable as an index of UBO's array
我尝试使用属性变量作为统一缓冲区对象中数组的索引。链接程序时出现链接错误,但遗憾的是没有其他错误描述。如果我在顶点着色器中将 a_Index
更改为常量,一切正常。
请帮助我))这里有什么问题?
这是我的顶点着色器:
#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);
}
片段着色器:
#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;
}
用于获取错误消息的代码(logLen
等于零):
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;
}
见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. [...]
请注意,“除了常数积分表达式之外的任何东西。” 正是您所做的(nodes[a_Index]
而不是 nodes[0]
)。
所以你有两个选择:
声明数组的大小。
使用一个Shader Storage Block instead of a Uniform Block。例如:
layout(std140, row_major) buffer LinesBuffer {
Node nodes[];
};
我尝试使用属性变量作为统一缓冲区对象中数组的索引。链接程序时出现链接错误,但遗憾的是没有其他错误描述。如果我在顶点着色器中将 a_Index
更改为常量,一切正常。
请帮助我))这里有什么问题?
这是我的顶点着色器:
#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);
}
片段着色器:
#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;
}
用于获取错误消息的代码(logLen
等于零):
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;
}
见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. [...]
请注意,“除了常数积分表达式之外的任何东西。” 正是您所做的(nodes[a_Index]
而不是 nodes[0]
)。
所以你有两个选择:
声明数组的大小。
使用一个Shader Storage Block instead of a Uniform Block。例如:
layout(std140, row_major) buffer LinesBuffer { Node nodes[]; };