101 lines
3.1 KiB
GLSL
101 lines
3.1 KiB
GLSL
/*
|
|
* Used the implementation of wide lines of Timo Suoranta (http://neure.dy.fi/wideline.html)
|
|
*/
|
|
|
|
#define PASSTHROUGH 0
|
|
|
|
layout(lines) in;
|
|
|
|
#if defined(DRAW_LINE)
|
|
|
|
#if PASSTHROUGH
|
|
layout(line_strip, max_vertices = 10) out;
|
|
#else
|
|
layout(triangle_strip, max_vertices = 6) out;
|
|
#endif
|
|
|
|
varying out float t;
|
|
varying in vec4 varying_vertex_color_line[];
|
|
varying out vec4 varying_vertex_color;
|
|
|
|
uniform ivec4 viewport;
|
|
uniform float line_width;
|
|
uniform int stipple_factor;
|
|
|
|
void main(void)
|
|
{
|
|
vec2 window_size = viewport.zw;
|
|
vec4 start = gl_in[0].gl_Position;
|
|
vec4 end = gl_in[1].gl_Position;
|
|
#if PASSTHROUGH
|
|
gl_Position = start; EmitVertex();
|
|
gl_Position = end; EmitVertex();
|
|
EndPrimitive();
|
|
return;
|
|
#endif
|
|
|
|
/* t = 0 t = ~(len(end - start) + 2*line_width)
|
|
* A-------------------------------------B
|
|
* | | | |
|
|
* | side | |
|
|
* | | | |
|
|
* |--axis--*start--------------*end-----|
|
|
* | | | |
|
|
* | | | |
|
|
* | | | |
|
|
* D-------------------------------------C
|
|
*/
|
|
|
|
/* Clip the line before homogenization.
|
|
* Compute line start and end distances to nearplane in clipspace
|
|
* Distances are t0 = dot(start, plane) and t1 = dot(end, plane)
|
|
*/
|
|
float t0 = start.z + start.w;
|
|
float t1 = end.z + end.w;
|
|
if (t0 < 0.0) {
|
|
if (t1 < 0.0) {
|
|
return;
|
|
}
|
|
start = mix(start, end, (0 - t0) / (t1 - t0));
|
|
}
|
|
if (t1 < 0.0) {
|
|
end = mix(start, end, (0 - t0) / (t1 - t0));
|
|
}
|
|
|
|
/* Compute line axis and side vector in screen space */
|
|
vec2 startInNDC = start.xy / start.w; /* clip to NDC: homogenize and drop z */
|
|
vec2 endInNDC = end.xy / end.w;
|
|
vec2 lineInNDC = endInNDC - startInNDC;
|
|
vec2 lineInScreen = lineInNDC * window_size; /* ndc to screen (direction vector) */
|
|
|
|
vec2 axisInScreen = normalize(lineInScreen);
|
|
vec2 sideInScreen = vec2(-axisInScreen.y, axisInScreen.x); /* rotate */
|
|
vec2 axisInNDC = axisInScreen / window_size; /* screen to NDC */
|
|
vec2 sideInNDC = sideInScreen / window_size;
|
|
vec4 axis = vec4(axisInNDC, 0.0, 0.0) * line_width; /* NDC to clip (delta vector) */
|
|
vec4 side = vec4(sideInNDC, 0.0, 0.0) * line_width;
|
|
|
|
vec4 A = (start + (side - axis) * start.w);
|
|
vec4 B = (end + (side + axis) * end.w);
|
|
vec4 C = (end - (side - axis) * end.w);
|
|
vec4 D = (start - (side + axis) * start.w);
|
|
|
|
/* There is no relation between lines yet */
|
|
/* TODO Pass here t0 to make continuous pattern. */
|
|
t0 = 0;
|
|
t1 = (length(lineInScreen) + 2 * line_width) / (2 * line_width * stipple_factor);
|
|
|
|
gl_Position = A; t = t0; varying_vertex_color = varying_vertex_color_line[0]; EmitVertex();
|
|
gl_Position = D; t = t0; varying_vertex_color = varying_vertex_color_line[0]; EmitVertex();
|
|
gl_Position = B; t = t1; varying_vertex_color = varying_vertex_color_line[1]; EmitVertex();
|
|
gl_Position = C; t = t1; varying_vertex_color = varying_vertex_color_line[1]; EmitVertex();
|
|
EndPrimitive();
|
|
}
|
|
|
|
#else
|
|
void main(void)
|
|
{
|
|
|
|
}
|
|
#endif
|