Your first problem is related to your use of discard
.
At present, you are discarding the fragments that do not lie within an appropriate distance from your wireframe in the fragment shader. That is incorrect behavior, this will only draw the wireframe.
What you need to do is actually replace the discard
with a different color.
if (d > u_halfLineWidth + 1.0)
{
//discard; // DO NOT DO THIS
//
// Instead, do this
//
fragmentColor = vec4 (0.0, 0.0, 0.0, 1.0);
return;
}
Granted this is going to produce a black filled mesh, but if you used the color u_color
, the filled part of the mesh would be indistinguishable from the wireframe. Ultimately you probably want to define a per-vertex color that is separate from the wireframe color, but it is up to you to figure out how to do that.
As for Question #2, that is solved by tweaking the edge distances:
The idea in the article you linked to was that for each triangle your geometry shader emits, it should write a distance to the opposite edge for each vertex. If you know that one of the edges in your triangle is an interior edge and thus should not be included in the wireframe, you should set the distance for the vertex opposite that edge far enough away that it never interpolates to 0 (or whatever width you chose for the wireframe).
The following modifications to your GS will remove the interior edges of the triangle strip:
void main()
{
vec2 p0 = windowPosition[0];
vec2 p1 = windowPosition[1];
vec2 p2 = windowPosition[2];
// Alternate between using the first and last vertex as the one opposite the
// interior edge based on primitive ID.
bool strip_flip = (bool (gl_PrimitiveIDIn & 1));
gl_Position = gl_in[0].gl_Position;
if (strip_flip)
distanceToEdges = vec3(og_distanceToLine(p0, p1, p2), 0.0, 0.0);
else
distanceToEdges = vec3(og_distanceToLine(p0, p1, p2), 0.0, 99999.0);
EmitVertex();
gl_Position = gl_in[1].gl_Position;
if (strip_flip)
distanceToEdges = vec3(99999.0, og_distanceToLine(p1, p2, p0), 0.0);
else
distanceToEdges = vec3(0.0, og_distanceToLine(p1, p2, p0), 99999.0);
EmitVertex();
gl_Position = gl_in[2].gl_Position;
if (strip_flip)
distanceToEdges = vec3(99999.0, 0.0, og_distanceToLine(p2, p0, p1));
else
distanceToEdges = vec3( 0.0, 0.0, og_distanceToLine(p2, p0, p1));
EmitVertex();
}
This works by alternating between first/last vertex serving as the vertex opposite the interior edge that the strip inserted. For each odd triangle, the interior edge is opposite the first vertex, for each even triangle it is opposite the last. This is fundamentally how triangle strips operate, the winding is reversed on each successive triangle and that makes it easy to identify which edge to remove.
To ensure that distanceToEdges
never interpolates to anything less than or equal to u_HalfLineWidth + 1.0
in the direction of this edge, said coordinates are pushed from their normal 0.0 value to 99999.0.
Thus, if you refer to the dashed edge in the following diagram, Q is 99999.0:
Imagine a triangle mirrored across that dashed edge and then you should have a pretty good idea of what the Geometry Shader is doing.