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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
/* Keep the same value of `ACTIVE_NURB` in `draw_cache_imp_curve.c` */
#define ACTIVE_NURB 1 << 2
#define EVEN_U_BIT 1 << 4
#define COLOR_SHIFT 5
/* Keep the same value in `handle_display` in `DNA_view3d_types.h` */
#define CURVE_HANDLE_SELECTED 0
#define CURVE_HANDLE_ALL 1
layout(lines) in;
layout(triangle_strip, max_vertices = 10) out;
uniform bool showCurveHandles;
uniform int curveHandleDisplay;
flat in int vertFlag[];
out vec4 finalColor;
void output_line(vec2 offset, vec4 color)
{
finalColor = color;
gl_Position = gl_in[0].gl_Position;
gl_Position.xy += offset * gl_in[0].gl_Position.w;
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_set_clip_distance(gl_in[0].gl_ClipDistance);
#endif
EmitVertex();
gl_Position = gl_in[1].gl_Position;
gl_Position.xy += offset * gl_in[1].gl_Position.w;
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_set_clip_distance(gl_in[1].gl_ClipDistance);
#endif
EmitVertex();
}
void main()
{
vec4 v1 = gl_in[0].gl_Position;
vec4 v2 = gl_in[1].gl_Position;
int is_active_nurb = (vertFlag[1] & ACTIVE_NURB);
int color_id = (vertFlag[1] >> COLOR_SHIFT);
/* Don't output any edges if we don't show handles */
if (!showCurveHandles && (color_id < 5)) {
return;
}
bool edge_selected = (((vertFlag[1] | vertFlag[0]) & VERT_SELECTED) != 0);
bool handle_selected = (showCurveHandles &&
(((vertFlag[1] | vertFlag[0]) & VERT_SELECTED_BEZT_HANDLE) != 0));
/* It reuses freestyle flag because the flag is 8 bits and all are already used and this
* flag is not used in this context. */
bool is_gpencil = ((vertFlag[1] & EDGE_FREESTYLE) != 0);
/* If handle type is only selected and the edge is not selected, don't show. */
if ((curveHandleDisplay != CURVE_HANDLE_ALL) && (!handle_selected)) {
/* Nurbs must show the handles always. */
bool is_u_segment = (((vertFlag[1] ^ vertFlag[0]) & EVEN_U_BIT) != 0);
if ((!is_u_segment) && (color_id <= 4)) {
return;
}
if (is_gpencil) {
return;
}
}
vec4 inner_color;
if (color_id == 0) {
inner_color = (edge_selected) ? colorHandleSelFree : colorHandleFree;
}
else if (color_id == 1) {
inner_color = (edge_selected) ? colorHandleSelAuto : colorHandleAuto;
}
else if (color_id == 2) {
inner_color = (edge_selected) ? colorHandleSelVect : colorHandleVect;
}
else if (color_id == 3) {
inner_color = (edge_selected) ? colorHandleSelAlign : colorHandleAlign;
}
else if (color_id == 4) {
inner_color = (edge_selected) ? colorHandleSelAutoclamp : colorHandleAutoclamp;
}
else {
bool is_selected = (((vertFlag[1] & vertFlag[0]) & VERT_SELECTED) != 0);
bool is_u_segment = (((vertFlag[1] ^ vertFlag[0]) & EVEN_U_BIT) != 0);
if (is_u_segment) {
inner_color = (is_selected) ? colorNurbSelUline : colorNurbUline;
}
else {
inner_color = (is_selected) ? colorNurbSelVline : colorNurbVline;
}
}
vec4 outer_color = (is_active_nurb != 0) ?
mix(colorActiveSpline,
inner_color,
0.25) /* Minimize active color bleeding on inner_color. */
:
vec4(inner_color.rgb, 0.0);
vec2 v1_2 = (v2.xy / v2.w - v1.xy / v1.w);
vec2 offset = sizeEdge * 4.0 * sizeViewportInv.xy; /* 4.0 is eyeballed */
if (abs(v1_2.x * sizeViewport.x) < abs(v1_2.y * sizeViewport.y)) {
offset.y = 0.0;
}
else {
offset.x = 0.0;
}
/* draw the transparent border (AA). */
if (is_active_nurb != 0) {
offset *= 0.75; /* Don't make the active "halo" appear very thick. */
output_line(offset * 2.0, vec4(colorActiveSpline.rgb, 0.0));
}
/* draw the outline. */
output_line(offset, outer_color);
/* draw the core of the line. */
output_line(vec2(0.0), inner_color);
/* draw the outline. */
output_line(-offset, outer_color);
/* draw the transparent border (AA). */
if (is_active_nurb != 0) {
output_line(offset * -2.0, vec4(colorActiveSpline.rgb, 0.0));
}
EndPrimitive();
}
|