Home > database >  Passing arrays to tesselation evaluation shader
Passing arrays to tesselation evaluation shader

Time:09-27

I have this 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;
}

The vertex specification:

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);

The render part:

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());    

I am trying to pass an array float f[6] and I crash my app if I don't comment the line indicated in the tesselation control shader. I don't understand what I'm doing wrong. I know for sure it is not the c part of the code. There are no errors when compiling the shaders or linking the program (opengl program).

CodePudding user response:

The size argument of glVertexAttribPointer must be 1, 2, 3 or 4. Passing 6 to the size argument generates a GL_INVALID_VALUE error.
If the type of the vertex shader attribute is an array, each element of the array has a separate attribute index. The attribute layout (location = 2) in float f[SIZE]; has the attribute indices from 2 to 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);
// [...]
  • Related