OpenGL Tessellation

I’m having a hard time getting OpenGL Tessellation to work. I have been struggling with it for about a month now. I’ve looked at a lot of example code and what I am doing doesn’t seem that different to what they are doing in their code. I was wondering if anyone could be a second pair of eyes and maybe point out why it isn’t working.

My scene is only rendering a black screen.

My shaders are as follows:

Vertex Shader
#version 150

in vec3 vertexPosition;
in vec3 vertexNormal;
in vec2 textureCoords;
in float textureIndex;

out VertexData
{
vec4 VertexPositions;
vec3 VertexNormals;
vec2 TextureCoords;
float TextureIndexs;
} vertex;

void main()
{
vertex.VertexPositions = vec4(vertexPosition, 1.0);
vertex.VertexNormals = vertexNormal;
vertex.TextureCoords = textureCoords;
vertex.TextureIndexs = textureIndex;
}

Tessellation Control Shader
#version 400

layout(vertices = 3) out;

in vec4 iVertexPositions;
in vec3 iVertexNormals;
in vec2 iTextureCoords;
in float iTextureIndexs;

out vec4 oVertexPositions;
out vec3 oVertexNormals;
out vec2 oTextureCoords;
out float oTextureIndexs;

void main()
{
float inLevel = 2;
float outLevel = 2;

gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
oVertexPositions[gl_InvocationID] = iVertexPositions[gl_InvocationID];
oVertexNormals[gl_InvocationID] = iVertexNormals[gl_InvocationID];
oTextureCoords[gl_InvocationID] = iTextureCoords[gl_InvocationID];
oVertexPositions[gl_InvocationID] = iVertexPositions[gl_InvocationID];

if (gl_InvocationID == 0)
{
	gl_TessLevelOuter[0] = outLevel;
	gl_TessLevelOuter[1] = outLevel;
	gl_TessLevelOuter[2] = outLevel;
	gl_TessLevelOuter[3] = outLevel;

	gl_TessLevelInner[0] = inLevel;
	gl_TessLevelInner[1] = inLevel;
}

}

Tessellation Eval Shader
#version 400

layout(triangles, equal_spacing, ccw) in;

uniform mat4 uMVPMatrix;

in vec4 iVertexPositions;
in vec3 iVertexNormals;
in vec2 iTextureCoords;
in float iTextureIndexs;

out VertexData
{
vec4 VertexPositions;
vec3 VertexNormals;
vec2 TextureCoords;
float TextureIndexs;
} vOut;

void main()
{
vec4 p0 = gl_TessCoord.x * iVertexPositions[0];
vec4 p1 = gl_TessCoord.y * iVertexPositions[1];
vec4 p2 = gl_TessCoord.z * iVertexPositions[2];

vec4 newCoord = normalize(p0 + p1 + p2);
vec3 normal = cross(vec3(p0 - newCoord), vec3(p1 - newCoord));

vOut.VertexPositions = newCoord;
vOut.VertexNormals =  normal;
vOut.TextureCoords = vec2(gl_TessCoord.xy);
vOut.TextureIndexs = iTextureIndexs[0];
gl_Position = newCoord;

}

Geometry Shader
#version 400

layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;

in VertexData
{
vec4 VertexPositions;
vec3 VertexNormals;
vec2 TextureCoords;
float TextureIndexs;
} vertex;

uniform vec3 LightNorm;
uniform vec4 LightIntensReflect;

uniform vec4 AmbientLight;
uniform vec4 VertColors;
uniform vec3 VertSpecularHighlight;

uniform vec3 CameraLocation;
uniform bool UseLighting;
uniform bool UseTexture;
uniform bool UseTextureArray;

uniform mat4 uMVPMatrix;
uniform mat4 DepthBiasMVP;
uniform mat3 uNMatrix;

uniform bool UseWaveGeometry;
uniform float GameTime;

out vec4 SpecularColor;
out vec4 LightShade;
out vec4 ShadowCoord;
out vec4 vColor;
out vec3 tCoord;

float rand(vec2 n)
{
return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);
}

void setUpValues(int index)
{
vec4 vertPosit = vertex[index].VertexPositions;
if(UseTexture)
{
tCoord = vec3(vertex[index].TextureCoords.st, vertex[index].TextureIndexs);
}
else
{
tCoord = vec3(0.0);
}

if(UseLighting)
{
	ShadowCoord = DepthBiasMVP * vertPosit;

	vec3 tnorm = normalize(uNMatrix * vertex[index].VertexNormals);		
	
	LightShade = LightIntensReflect * max(dot(LightNorm, tnorm), 0.0);
	
	SpecularColor = vec4(1.0);
	vColor = LightShade * VertColors + (AmbientLight * VertColors);
}
else
{
	SpecularColor = vec4(1.0);
	ShadowCoord = vec4(0.0);
	LightShade = vec4(1.0);
	vColor = VertColors;
}

if(UseWaveGeometry)
{
	vertPosit.y = vertPosit.y + (GameTime + ((cos(vertPosit.x)) * GameTime) - ((sin(vertPosit.x))*GameTime)*2.2);
}

gl_Position = uMVPMatrix * vertPosit;

}

void main()
{
for(int i = 0; i < 3; i++)
{
setUpValues(i);
EmitVertex();
}
EndPrimitive();
}

Fragment Shader
#version 150
#extension GL_EXT_gpu_shader4: enable
#extension GL_EXT_texture_array: enable

uniform sampler2DShadow ShadowMap;
uniform sampler2D TextureData;
uniform sampler2DArray TextureArrayData;

uniform vec4 AmbientLight;
uniform bool UseLighting;
uniform bool UseTexture;
uniform bool UseTextureArray;
uniform bool UseAlpha;
uniform float ColorAlpha;

in vec4 SpecularColor;
in vec4 vColor;
in vec4 LightShade;
in vec4 ShadowCoord;
in vec3 tCoord;

out vec4 FragColor;

void main()
{
vec4 color = vec4(1.0);
float Shadow = 1.0;
if(UseTexture)
{
if(UseTextureArray)
{
color = texture2DArray(TextureArrayData, tCoord.stp);
}
else
{
color = texture2D(TextureData, tCoord.st);
}

	if(UseAlpha)
	{
		color = vec4(color.r, color.g, color.b, ColorAlpha);
	}

	if(UseLighting)
	{
		if(ShadowCoord.w > 0.0)
		{
			Shadow = textureProj(ShadowMap, ShadowCoord);
		}

		FragColor = ((LightShade * color) * Shadow + (color * AmbientLight)) * SpecularColor;
	}
	else
	{
		FragColor = color;
	}
}
else
{
	if(UseLighting)
	{
		Shadow = textureProj(ShadowMap, ShadowCoord);
	}
	
	if(UseAlpha)
	{
		color = vec4(vColor.r, vColor.g, vColor.b, ColorAlpha);
	}

	FragColor = color * Shadow * SpecularColor;
}

}

Thank you for your time,
Marty

I’ve cleaned up my shaders to simplify the code. Right now there is just the tessellation code.

Vertex Shader

#version 400
#extension GL_ARB_tessellation_shader: enable
#extension GL_ARB_separate_shader_objects: enable

layout(location = 0) in vec3 vertexPosition;

void main()
{
gl_Position = vec4(vertexPosition, 1.0);
}

Tessellation Control Shader

#version 400
#extension GL_ARB_separate_shader_objects: enable

layout(vertices = 3) out;

void main()
{
float inLevel = 2;
float outLevel = 2;

gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

if (gl_InvocationID == 0)
{
    gl_TessLevelOuter[0] = outLevel;
    gl_TessLevelOuter[1] = outLevel;
    gl_TessLevelOuter[2] = outLevel;
    gl_TessLevelOuter[3] = outLevel;

    gl_TessLevelInner[0] = inLevel;
    gl_TessLevelInner[1] = inLevel;
}

}

Tessellation Eval Shader

#version 400
#extension GL_ARB_tessellation_shader: enable
#extension GL_ARB_separate_shader_objects: enable

layout(triangles, equal_spacing, ccw) in;

uniform mat4 uMVPMatrix;

void main()
{
vec4 p0 = gl_TessCoord.x * gl_in[0].gl_Position;
vec4 p1 = gl_TessCoord.y * gl_in[1].gl_Position;
vec4 p2 = gl_TessCoord.z * gl_in[2].gl_Position;

vec4 newCoord = normalize(p0 + p1 + p2);
gl_Position = newCoord;

}

Geometry Shader

#version 400
#extension GL_ARB_separate_shader_objects: enable

layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;

uniform mat4 uMVPMatrix;

uniform bool UseWaveGeometry;
uniform float GameTime;

layout(location = 3) out vec4 vColor;

float rand(vec2 n)
{
return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);
}

void setUpValues(int index)
{
vec4 vertPosit = gl_in[index].gl_Position;

if(UseWaveGeometry)
{
    vertPosit.y = vertPosit.y + (GameTime + ((cos(vertPosit.x)) * GameTime) - ((sin(vertPosit.x))*GameTime)*2.2);
}

float cval = int(vertPosit.x) % 2 + int(vertPosit.y)%2;
vColor = vec4(cval, cval, cval, 1.0);

gl_Position = uMVPMatrix * vertPosit;

}

void main()
{
for(int i = 0; i < 3; i++)
{
setUpValues(i);
EmitVertex();
}
EndPrimitive();
}

Fragment Shader

#version 400
#extension GL_EXT_gpu_shader4: enable
#extension GL_ARB_separate_shader_objects: enable

uniform float ColorAlpha;

layout(location = 3) in vec4 vColor;

layout(location = 0) out vec4 FragColor;

void main()
{
vec4 color = vec4(vColor.r, vColor.g, vColor.b, ColorAlpha);

FragColor = color;

}

I figured out my issue. The problem is when I called glDrawArrays I was passing in GL_TRIANGLES instead of GL_PATCHES