使用顶点属性变量作为 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])。

所以你有两个选择:

  1. 声明数组的大小。

  2. 使用一个Shader Storage Block instead of a Uniform Block。例如:

    layout(std140, row_major) buffer LinesBuffer {
        Node nodes[];
    };