Search code examples
glslshadertessellation

Tessellation shader drawing issues


I am currently trying to add tessellation shaders to my program and I feel as though I'm at my wit's end. I have gone through several tutorials and delved into a lot of the questions here as well. Unfortunately I still do not understand what I am doing wrong after all of this. I will take any tips gladly, and do admit I'm a total novice here. My vertex and fragment shaders work, but no matter which tutorial I base my code off of, I can not get anything to display once I add tessellation shaders. I get no errors while loading, linking, or using the shaders/program either.

The four shaders in question:

Vertex:

layout (location = 0) in vec4 vertex;

out gl_PerVertex{
vec4 gl_Position;
};

void main()
{
gl_Position = gl_Vertex;
//note I have to multiply this by the MVP matrix if there is no tessellation
}

Tessellation Control Shader:

layout (vertices = 3) out;

out gl_PerVertex {
 vec4 gl_Position;
 } gl_out[];

void main()
{
if (gl_InvocationID == 0)
   {
   gl_TessLevelInner[0] = 3.0;
   gl_TessLevelOuter[0] = 2.0;
   gl_TessLevelOuter[1] = 2.0;
   gl_TessLevelOuter[2] = 2.0;
   }
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

Tessellation Evaluation Shader:

layout(triangles, equal_spacing, ccw) in;
uniform mat4 ModelViewProjectionMatrix;
out gl_PerVertex{
vec4 gl_Position;
};

void main()
{
 vec4 position =    gl_TessCoord.x * gl_in[0].gl_Position +
                    gl_TessCoord.y * gl_in[1].gl_Position +
                    gl_TessCoord.z * gl_in[2].gl_Position;
 gl_Position = ModelViewProjectionMatrix * position;
}

Fragment Shader:

void main()
{
gl_FragColor = vec4(0.1, 0.4, 0.0, 1.0);
}

I'm sure I'm overlooking some really simple stuff here, but I'm at an absolute loss here. Thanks for taking the time to read this.


Solution

  • When you draw using a Tessellation Control Shader (this is an optional stage), you must use GL_PATCHES as the primitive type.

    Additionally, GL_PATCHES has no default number of vertices, you must set that:

    glPatchParameteri (GL_PATCH_VERTICES​, 3);
    glDrawElements    (GL_PATCHES, 3, ..., ...);
    

    The code listed above will draw a single triangle patch. Now, since geometry shaders and tessellation evaluation shaders do not understand GL_PATCHES, if you remove the tessellation control shader, the draw code will do nothing. Only the tessellation control shader can make sense out of GL_PATCHES primitive, and conversely it cannot make sense of any other kind of primitive.