2020-02-03 10:52:39 -08:00
|
|
|
#version 330
|
|
|
|
|
|
|
|
layout (triangles) in;
|
|
|
|
layout (triangle_strip, max_vertices = 5) out;
|
|
|
|
|
|
|
|
uniform float scale;
|
|
|
|
uniform float aspect_ratio;
|
|
|
|
uniform float anti_alias_width;
|
2020-02-11 19:49:54 -08:00
|
|
|
uniform vec3 frame_center;
|
2020-02-03 10:52:39 -08:00
|
|
|
|
2020-02-16 10:53:16 -08:00
|
|
|
in vec3 bp[3];
|
2020-02-03 10:52:39 -08:00
|
|
|
in vec4 v_color[3];
|
2020-02-07 09:31:57 -08:00
|
|
|
in float v_fill_all[3];
|
2020-02-03 10:52:39 -08:00
|
|
|
|
|
|
|
out vec4 color;
|
2020-05-31 17:02:05 -07:00
|
|
|
out float fill_all;
|
2020-02-03 10:52:39 -08:00
|
|
|
out float uv_anti_alias_width;
|
|
|
|
// uv space is where b0 = (0, 0), b1 = (1, 0), and transform is orthogonal
|
|
|
|
out vec2 uv_coords;
|
|
|
|
out vec2 uv_b2;
|
|
|
|
|
|
|
|
out float bezier_degree;
|
|
|
|
|
|
|
|
const float FILL_INSIDE = 0;
|
|
|
|
const float FILL_OUTSIDE = 1;
|
|
|
|
const float FILL_ALL = 2;
|
|
|
|
|
|
|
|
const float SQRT5 = 2.236068;
|
|
|
|
|
|
|
|
|
|
|
|
// To my knowledge, there is no notion of #include for shaders,
|
|
|
|
// so to share functionality between this and others, the caller
|
|
|
|
// replaces this line with the contents of named file
|
|
|
|
#INSERT quadratic_bezier_geometry_functions.glsl
|
2020-02-16 10:53:16 -08:00
|
|
|
#INSERT scale_and_shift_point_for_frame.glsl
|
2020-02-03 10:52:39 -08:00
|
|
|
|
|
|
|
void emit_simple_triangle(){
|
|
|
|
for(int i = 0; i < 3; i++){
|
|
|
|
color = v_color[i];
|
2020-02-16 10:53:16 -08:00
|
|
|
gl_Position = vec4(
|
|
|
|
scale_and_shift_point_for_frame(bp[i]),
|
|
|
|
1.0
|
|
|
|
);
|
2020-02-03 10:52:39 -08:00
|
|
|
EmitVertex();
|
|
|
|
}
|
|
|
|
EndPrimitive();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-31 17:02:05 -07:00
|
|
|
void emit_pentagon(vec2 bp0, vec2 bp1, vec2 bp2){
|
2020-02-03 10:52:39 -08:00
|
|
|
// Tangent vectors
|
|
|
|
vec2 t01 = normalize(bp1 - bp0);
|
|
|
|
vec2 t12 = normalize(bp2 - bp1);
|
2020-02-07 09:31:57 -08:00
|
|
|
// Normal vectors
|
|
|
|
// Rotate tangent vector 90-degrees clockwise
|
2020-05-31 17:02:05 -07:00
|
|
|
vec2 n01 = vec2(t01.y, -t01.x);
|
|
|
|
vec2 n12 = vec2(t12.y, -t12.x);
|
|
|
|
|
|
|
|
float c_orient = sign(cross(t01, t12));
|
|
|
|
bool fill_in = (c_orient > 0);
|
2020-02-07 09:31:57 -08:00
|
|
|
|
|
|
|
float aaw = anti_alias_width;
|
|
|
|
vec2 nudge1 = fill_in ? 0.5 * aaw * (n01 + n12) : vec2(0);
|
2020-02-03 10:52:39 -08:00
|
|
|
vec2 corners[5] = vec2[5](
|
|
|
|
bp0 + aaw * n01,
|
|
|
|
bp0,
|
|
|
|
bp1 + nudge1,
|
|
|
|
bp2,
|
|
|
|
bp2 + aaw * n12
|
|
|
|
);
|
|
|
|
|
|
|
|
int coords_index_map[5] = int[5](0, 1, 2, 3, 4);
|
2020-02-07 09:31:57 -08:00
|
|
|
if(!fill_in) coords_index_map = int[5](1, 0, 2, 4, 3);
|
2020-02-03 10:52:39 -08:00
|
|
|
|
|
|
|
mat3 xy_to_uv = get_xy_to_uv(bp0, bp1);
|
|
|
|
uv_b2 = (xy_to_uv * vec3(bp2, 1)).xy;
|
|
|
|
uv_anti_alias_width = anti_alias_width / length(bp1 - bp0);
|
|
|
|
|
2020-05-31 17:02:05 -07:00
|
|
|
int nearest_bp_index_map[5] = int[5](0, 0, 1, 2, 2);
|
2020-02-03 10:52:39 -08:00
|
|
|
for(int i = 0; i < 5; i++){
|
|
|
|
vec2 corner = corners[coords_index_map[i]];
|
2020-05-31 17:02:05 -07:00
|
|
|
float z = bp[nearest_bp_index_map[i]].z;
|
2020-02-03 10:52:39 -08:00
|
|
|
uv_coords = (xy_to_uv * vec3(corner, 1)).xy;
|
|
|
|
// I haven't a clue why an index map doesn't work just
|
|
|
|
// as well here, but for some reason it doesn't.
|
2020-05-31 17:02:05 -07:00
|
|
|
if(i < 2) color = v_color[0];
|
|
|
|
else if(i == 2) color = v_color[1];
|
|
|
|
else color = v_color[2];
|
2020-02-16 10:53:16 -08:00
|
|
|
gl_Position = vec4(
|
|
|
|
scale_and_shift_point_for_frame(vec3(corner, z)),
|
|
|
|
1.0
|
|
|
|
);
|
2020-02-03 10:52:39 -08:00
|
|
|
EmitVertex();
|
|
|
|
}
|
|
|
|
EndPrimitive();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void main(){
|
2020-05-31 17:02:05 -07:00
|
|
|
fill_all = v_fill_all[0];
|
2020-02-03 10:52:39 -08:00
|
|
|
|
2020-02-07 09:31:57 -08:00
|
|
|
if(fill_all == 1){
|
2020-02-03 10:52:39 -08:00
|
|
|
emit_simple_triangle();
|
2020-05-31 17:02:05 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vec2 new_bp[3];
|
|
|
|
int n = get_reduced_control_points(bp[0].xy, bp[1].xy, bp[2].xy, new_bp);
|
|
|
|
bezier_degree = float(n);
|
|
|
|
vec2 bp0, bp1, bp2;
|
|
|
|
if(n == 0){
|
|
|
|
return; // Don't emit any vertices
|
|
|
|
}
|
|
|
|
else if(n == 1){
|
|
|
|
bp0 = new_bp[0];
|
|
|
|
bp2 = new_bp[1];
|
|
|
|
bp1 = 0.5 * (bp0 + bp2);
|
2020-02-03 10:52:39 -08:00
|
|
|
}else{
|
2020-05-31 17:02:05 -07:00
|
|
|
bp0 = new_bp[0];
|
|
|
|
bp1 = new_bp[1];
|
|
|
|
bp2 = new_bp[2];
|
2020-02-03 10:52:39 -08:00
|
|
|
}
|
2020-05-31 17:02:05 -07:00
|
|
|
|
|
|
|
emit_pentagon(bp0, bp1, bp2);
|
2020-02-03 10:52:39 -08:00
|
|
|
}
|
|
|
|
|