0
\$\begingroup\$

Using this tutorial https://learnopengl.com/Guest-Articles/2021/Tessellation/Tessellation and this tutorial https://www.youtube.com/watch?v=21gfE-zUym8 I implemented tessellation shaders that I haven't been able to get working after debugging for 8 hours. The error message I get is enter image description here

This is what my window is looking like enter image description here

This is my tessellation control shader

#version 410 core

// specify control points per output per patch
// control size of input and output arrays
layout(vertices=3) out;
// input from vertex shader
in vec2 vert_coord[];
// output to evaluation shader
out vec2 vertex_coord[];

// for tessellation
uniform mat4 view;
uniform mat4 model;

void main()
{
    // pass attributes through
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
    vertex_coord[gl_InvocationID] = vert_coord[gl_InvocationID];

    // control tessellation
    if(gl_InvocationID==0)
    {
        /* dynamic tessellation */
        // first: define rendering constants to control tessellation
        const float MIN_TESS_LEVEL = 4;
        const float MAX_TESS_LEVEL = 64;
        const float MIN_DISTANCE = 20;
        const float MAX_DISTANCE = 800;
        // second: transform each vertex into each eye
        vec4 eye_space_pos_1 = view * model * gl_in[0].gl_Position;
        vec4 eye_space_pos_2 = view * model * gl_in[1].gl_Position;
        vec4 eye_space_pos_3 = view * model * gl_in[2].gl_Position;
        // third: distance from camera scaled between 0 and 1
        float distance_1 = clamp((abs(eye_space_pos_1.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        float distance_2 = clamp((abs(eye_space_pos_2.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        float distance_3 = clamp((abs(eye_space_pos_3.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0);
        // fourth: interpolate edge tessellation level based on closer vertex
        float tess_level_1 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_3, distance_1));
        float tess_level_2 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_1, distance_2));
        float tess_level_3 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_2, distance_3));
        // fifth: set the corresponding outer tessellation levels
        gl_TessLevelOuter[0] = tess_level_1;
        gl_TessLevelOuter[1] = tess_level_2;
        gl_TessLevelOuter[2] = tess_level_3;
        // sixth: set the inner tessellation levels
        gl_TessLevelInner[0] = max(tess_level_1, tess_level_3);
        gl_TessLevelInner[1] = max(tess_level_1, tess_level_2);
    }
}

This is the tessellation evaluation shader

#version 410 core

// from control shader
layout(triangles, equal_spacing, ccw) in;

// input from control shader
in vec2 vertex_coord[];
// output vec
out vec2 vert;

// allows for object transformations and for movement
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    // patch coords
    float u = gl_TessCoord.x;
    float v = gl_TessCoord.y;
    float w = gl_TessCoord.z;

    // barycentric interpolation
    vec2 tex_coord = u * vertex_coord[0] + v * vertex_coord[1] + w * vertex_coord[2];

    // get control coords
    vec4 pos_1 = gl_in[0].gl_Position;
    vec4 pos_2 = gl_in[1].gl_Position;
    vec4 pos_3 = gl_in[2].gl_Position;

    // more barycentric interpolation
    vec4 pos = u * pos_1 + v * pos_2 + w * pos_3;

    // position
    gl_Position = model * view * projection * pos;
    vert = tex_coord;
}

This is the vertex shader

#version 410 core

// position of the object
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 vert;

out vec2 vert_coord;

void main()
{
    // position object
    gl_Position = vec4(pos, 1.0f);
    vert_coord = vert;
}

This is the fragment shader

#version 410 core

out vec4 color;

void main()
{
    color = vec4(0.86f, 0.74f, 0.09f, 1.0f);
}

This is the shader loader for the tessellation shaders

// tess control
tessellation_control_shader = glCreateShader(GL_TESS_CONTROL_SHADER);
glShaderSource(tessellation_control_shader, 1, &tessellation_control_shader_text, NULL);
glCompileShader(tessellation_control_shader);
glGetShaderiv(tessellation_control_shader, GL_COMPILE_STATUS, &success);
if(!success)
{
    glGetShaderInfoLog(tessellation_control_shader, 512, NULL, info_log);
    printf("Tessellation control shader failed: %s\n", info_log);
    perror(info_log);
}

// tess eval
tessellation_evaluation_shader = glCreateShader(GL_TESS_EVALUATION_SHADER);
glShaderSource(tessellation_evaluation_shader, 1, &tessellation_evaluation_shader_text, NULL);
glCompileShader(tessellation_evaluation_shader);
glGetShaderiv(tessellation_evaluation_shader, GL_COMPILE_STATUS, &success);
if(!success)
{
    glGetShaderInfoLog(tessellation_evaluation_shader, 512, NULL, info_log);
    printf("Tessellation evaluation shader failed: %s\n", info_log);
    perror(info_log);
}

This is the tessellation initialization, vertices, indices and, buffers

 #define NUM_PATCH_PTS 3
    // shader loading
    unsigned int shader_program = load_shaders("vert.glsl", "frag.glsl", "tes_ctrl.glsl", "tes_eval.glsl");

    // octahedron, vertices provided by https://gamedev.stackexchange.com/users/39518/dmgregory
    unsigned int draw_calls = 48;
    float vertices[] = {
        //top-north-east
         0.0,  1.0,  0.0,
         0.0,  0.0,  1.0,
         1.0,  0.0,  0.0,

        //top-north-west
         0.0,  1.0,  0.0,
        -1.0,  0.0,  0.0,
         0.0,  0.0,  1.0,

        //top-south-west
         0.0,  1.0,  0.0,
         0.0,  0.0, -1.0,
        -1.0,  0.0,  0.0,

        //top-south-east
         0.0,  1.0,  0.0,
         1.0,  0.0,  0.0,
         0.0,  0.0, -1.0,

        //bottom-north-east
         0.0, -1.0,  0.0,
         1.0,  0.0,  0.0,
         0.0,  0.0,  1.0,

        //bottom-north-west
         0.0, -1.0,  0.0,
         0.0,  0.0,  1.0,
        -1.0,  0.0,  0.0,

        //bottom-south-west
         0.0, -1.0,  0.0,
        -1.0,  0.0,  0.0,
         0.0,  0.0, -1.0,

        //bottom-south-east
         0.0, -1.0,  0.0,
         0.0,  0.0, -1.0,
         1.0,  0.0,  0.0,
};

    unsigned int indices[] = {
        // first triangle
        0, 1, 2,
        // second triangle
        3, 4, 5,
        // third triangle
        6, 7, 8,
        // fourth triangle
        9, 10, 11,
        // fifth triangle
        12, 13, 14,
        // sixth triangle
        15, 16, 17,
        // seventh triangle
        18, 19, 20,
        // eighth triangle
        21, 22, 23
    };
    unsigned int vbo, vao, ebo;
    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);

    glBindVertexArray(vao);

    // upload vertex data to gpu
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) * sizeof(double), &vertices[0], GL_STATIC_DRAW);

    // upload index data to gpu
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices) * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // max tessellation points / patches
    glPatchParameteri(GL_PATCH_VERTICES, NUM_PATCH_PTS);

This is the draw call

    glBindVertexArray(vao);
    glDrawArrays(GL_PATCHES, 0, draw_calls*draw_calls*NUM_PATCH_PTS);
\$\endgroup\$
0

1 Answer 1

0
\$\begingroup\$

Step one: go here https://learnopengl.com/Guest-Articles/2021/Tessellation/Tessellation

Step two: change code from quads to triangles, this includes vectors, matrices, other math things, etc. Example: from layout (quads) to layout (triangles), vec2 vertex_coords to vec3 vertex_coords references: https://prideout.net/blog/old/blog/index.html@p=48.html https://www.khronos.org/opengl/wiki/Tessellationhttps://ogldev.org/www/tutorial30/tutorial30.html https://ogldev.org/www/tutorial30/tutorial30.html

Step three: This problem is solved, still a lot more but this one is done

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .