1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
/*
* 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
|