I am trying to implement single-pass wireframe, but I have got couple of issues in the process.
Question #1
For some reasons I get only wireframe without (like with glPolygoneMode
- lines) filled geometry after my geometry shader worked.
)
But if I disable the geometry shader I get my geometry:
What I really like to achieve is both geometry and its wireframe.
Question #2
Actually, my primitives are triangle strips. I use them to avoid using on quads to improve performance. How can I skip edges of wireframe while drawing? (I've already saw post how it can be done, but it is still not to clear for me.)
Here are my shaders:
Vertex shader:
#version 330
//
// (C) Copyright 2010 Patrick Cozzi and Deron Ohlarik
//
// Distributed under the MIT License.
// See License.txt or http://www.opensource.org/licenses/mit-license.php.
//
layout(location = 0) in vec3 in_Position;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 og_viewportTransformationMatrix;
out vec2 windowPosition;
vec4 og_ClipToWindowCoordinates(vec4 v, mat4 viewportTransformationMatrix);
void main()
{
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0);
windowPosition = og_ClipToWindowCoordinates(gl_Position, og_viewportTransformationMatrix).xy;
}
vec4 og_ClipToWindowCoordinates(vec4 v, mat4 viewportTransformationMatrix)
{
v.xyz /= v.w; // normalized device coordinates
v.xyz = (viewportTransformationMatrix * vec4(v.xyz, 1.0)).xyz; // window coordinates
return v;
}
Geomerty shader:
#version 330
//
// (C) Copyright 2010 Patrick Cozzi and Deron Ohlarik
//
// Distributed under the MIT License.
// See License.txt or http://www.opensource.org/licenses/mit-license.php.
//
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in vec2 windowPosition[];
noperspective out vec3 distanceToEdges;
float og_distanceToLine(vec2 f, vec2 p0, vec2 p1);
void main()
{
vec2 p0 = windowPosition[0];
vec2 p1 = windowPosition[1];
vec2 p2 = windowPosition[2];
gl_Position = gl_in[0].gl_Position;
distanceToEdges = vec3(og_distanceToLine(p0, p1, p2), 0.0, 0.0);
EmitVertex();
gl_Position = gl_in[1].gl_Position;
distanceToEdges = vec3(0.0, og_distanceToLine(p1, p2, p0), 0.0);
EmitVertex();
gl_Position = gl_in[2].gl_Position;
distanceToEdges = vec3(0.0, 0.0, og_distanceToLine(p2, p0, p1));
EmitVertex();
}
float og_distanceToLine(vec2 f, vec2 p0, vec2 p1)
{
vec2 l = f - p0;
vec2 d = p1 - p0;
//
// Closed point on line to f
//
vec2 p = p0 + (d * (dot(l, d) / dot(d, d)));
return distance(f, p);
}
Fragment shader:
#version 330
//
// (C) Copyright 2010 Patrick Cozzi and Deron Ohlarik
//
// Distributed under the MIT License.
// See License.txt or http://www.opensource.org/licenses/mit-license.php.
//
uniform float u_halfLineWidth;
uniform vec3 u_color;
noperspective in vec3 distanceToEdges;
out vec4 fragmentColor;
void main()
{
float d = min(distanceToEdges.x, min(distanceToEdges.y, distanceToEdges.z));
if (d > u_halfLineWidth + 1.0)
{
discard;
}
d = clamp(d - (u_halfLineWidth - 1.0), 0.0, 2.0);
fragmentColor = vec4(u_color, exp2(-2.0 * d * d));
}
Help me to figure out where I've got it wrong.
Update:
I have updated Fragment shader
and Geometry shader
as mention Andon M. Coleman in his answer, but problem described in Question 2 still not solved.
Update 2
I have just make some little edits in fragmet shader and that solves my problem.
Update fragment shader
#version 330
//
// (C) Copyright 2010 Patrick Cozzi and Deron Ohlarik
//
// Distributed under the MIT License.
// See License.txt or http://www.opensource.org/licenses/mit-license.php.
//
uniform float u_halfLineWidth;
uniform vec3 u_color;
noperspective in vec3 distanceToEdges;
out vec4 fragmentColor;
void main()
{
float d = min(distanceToEdges.y, max(distanceToEdges.x, distanceToEdges.z));
if (d > u_halfLineWidth + 1.0)
{
fragmentColor = vec4(u_color, 1);
return;
}
fragmentColor = vec4(vec3(0,0,0), 1);
}