将数组传递给曲面细分评估着色器

Passing arrays to tesselation evaluation shader

我有这个细分评估着色器:

\ vertex
#version 410 core
#define SIZE 6
layout (location = 0) in vec2 x;
layout (location = 1) in vec2 h;
layout (location = 2) in float f[SIZE];

out TC_DATA
{
    vec2 x;
    vec2 h;
    float f[SIZE];
} tc_out;

void main()
{
    tc_out.x = x;
    tc_out.h = h;
    tc_out.f = f;
}

\ tess control
#version 410
layout (vertices = 1) out;
#define SIZE 6

uniform int outer0;
uniform int outer1;
uniform int outer2;
uniform int inner;


in TC_DATA
{
    vec2 x;
    vec2 h;
    float f[SIZE];
} tc_in[];

out TE_DATA
{
    vec2 x;
    vec2 h;
    float f[SIZE];
} te_out[];

void main()
{
    if (gl_InvocationID == 0)
    {
        gl_TessLevelInner[0] = inner;
        gl_TessLevelOuter[0] = outer0;
        gl_TessLevelOuter[1] = outer1;
        gl_TessLevelOuter[2] = outer2;
    }
    te_out[gl_InvocationID].x = tc_in[gl_InvocationID].x;
    te_out[gl_InvocationID].h = tc_in[gl_InvocationID].h;
    // te_out[gl_InvocationID].f = tc_in[gl_InvocationID].f;  // <---- uncommenting this line crashes the app
}

\ tess evaluation
#version 410
layout (triangles) in;

out vec4 fColor;

void main()
{
    gl_Position = vec4(1.0);
    fColor = vec4(1.0);
}

\ fragment
#version 410 core
in vec4 fColor;
out vec4 oColor;

void main()
{
    oColor = fColor;
}

顶点规范:

struct Vertex 
{
    glm::vec2 x;
    glm::vec2 h;
    std::array<float, 6> f;
};
std::vector<Vertex> vertices;
//  ....
glGenVertexArrays(1, &vertex_array);
glBindVertexArray(vertex_array);
glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, h));
glVertexAttribPointer(2, 6, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, f));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);

渲染部分:

glPatchParameteri(GL_PATCH_VERTICES, 1);
glBindVertexArray(vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(decltype(vertices)::value_type), vertices.data(), GL_DYNAMIC_DRAW);        
glDrawArrays(GL_PATCHES, 0, vertices.size());    

我正在尝试传递一个数组 float f[6],但如果我不注释曲面细分控制着色器中指示的行,我的应用程序就会崩溃。我不明白我做错了什么。我确定它不是代码的 C++ 部分。编译着色器或链接程序(opengl程序)时没有错误。

glVertexAttribPointersize 参数必须为 1、2、3 或 4。将 6 传递给 size 参数生成 GL_INVALID_VALUE 错误。
如果顶点着色器属性的类型是数组,则数组的每个元素都有一个单独的属性索引。属性 layout (location = 2) in float f[SIZE]; 具有从 2 到 7 的属性索引:

glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 
    sizeof(Vertex), (void*)offsetof(Vertex, f));
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 
    sizeof(Vertex), (void*)(offsetof(Vertex, f) + 4));
glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, 
    sizeof(Vertex), (void*)(offsetof(Vertex, f) + 8));
// [...]
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
// [...]