#version 460
#extension GL_GOOGLE_include_directive : enable
#include <light.h>
#include <transform.h>
#include "links-shdr-common.h"
#include "shader-common-generic-lighting.h"
layout ( binding = BIND_UNI_COMMON ) uniform Common_Uniform
{
Shdr_Uni_Common com;
};
bool opt_tryout1 = bool(com.tryout.x);
bool opt_tryout2 = bool(com.tryout.y);
float opt_tryoutf = com.tryoutf.x;
const int TX_None = 0, TX_Square = 1, TX_Circle = 2;
layout ( binding = BIND_HW05 ) uniform HW_05
{
vec4 color;
int opt_texture;
float ring_hole_frac, one_over_delta_r, dy_d_theta;
};
#ifdef BIND_LINKS_POS1
layout ( binding = BIND_LINKS_POS1 ) buffer sr { vec4 pos1[]; };
layout ( binding = BIND_LINKS_POS2 ) buffer sr2 { vec4 pos2[]; };
layout ( binding = BIND_LINKS_V1 ) buffer spr { vec4 v1[]; };
layout ( binding = BIND_LINKS_V2 ) buffer sc { vec4 v2[]; };
#endif
#ifdef _VERTEX_SHADER_
layout ( location = LOC_IN_INT1 ) in int in_link_idx;
layout ( location = LOC_IN_POS ) in vec4 in_pack;
layout ( location = 0 ) out Data_to_GS
{
vec4 p1, p2, v1, v2;
vec2 tc1, tc2;
} Out;
void
vs_hw05()
{
Out.tc1 = in_pack.xy;
Out.tc2 = in_pack.zw;
Out.p1 = pos1[in_link_idx];
Out.p2 = pos2[in_link_idx];
Out.v1 = v1[in_link_idx];
Out.v2 = v2[in_link_idx];
}
#endif
#ifdef _GEOMETRY_SHADER_
layout ( location = 0 ) in Data_to_GS
{
vec4 p1, p2, v1, v2;
vec2 tc1, tc2;
} In[];
layout ( location = 0 ) out Data_to_FS
{
vec3 normal_e;
vec4 vertex_e;
vec2 tex_coor;
} Out;
layout ( lines ) in;
layout ( triangle_strip, max_vertices = 2 * ( opt_segments + 1 ) ) out;
vec4
bez(vec4 p1, vec4 p2, vec4 v1, vec4 v2, float t)
{
float t2 = t * t;
float t3 = t2 * t;
return
vec4( ( 2*t3 - 3*t2 + 1 ) * p1.xyz
+ ( -2*t3 + 3*t2 ) * p2.xyz
+ ( t3 - 2*t2 + t ) * v1.xyz
- ( t3 - t2 ) * v2.xyz,
1 );
}
vec3
bez_dt(vec4 p1, vec4 p2, vec4 v1, vec4 v2, float t)
{
float t2 = t * t;
float t3 = t2 * t;
return
( 6*t2 - 6*t ) * p1.xyz
+ ( -6*t2 + 6*t ) * p2.xyz
+ ( 3*t2 - 4*t + 1 ) * v1.xyz
- ( 3*t2 - 2*t ) * v2.xyz;
}
void
gs_hw05()
{
float delta_t = 1.0 / opt_segments;
for ( int s=0; s<=opt_segments; s++ )
{
float t = s * delta_t;
vec4 pos0t_o = bez( In[0].p1, In[0].p2, In[0].v1, In[0].v2, t );
vec4 pos1t_o = bez( In[1].p1, In[1].p2, In[1].v1, In[1].v2, t );
vec3 tan0 = bez_dt( In[0].p1, In[0].p2, In[0].v1, In[0].v2, t );
vec3 tan1 = bez_dt( In[1].p1, In[1].p2, In[1].v1, In[1].v2, t );
vec3 vx = pos1t_o.xyz - pos0t_o.xyz;
gl_Position = ut.clip_from_object * pos0t_o;
Out.vertex_e = ut.eye_from_object * pos0t_o;
Out.tex_coor = mix( In[0].tc1, In[0].tc2, t );
vec3 normal_1_o = cross( tan0, vx );
Out.normal_e = normalize( mat3(ut.eye_from_object) * normal_1_o );
EmitVertex();
gl_Position = ut.clip_from_object * pos1t_o;
Out.vertex_e = ut.eye_from_object * pos1t_o;
Out.tex_coor = mix( In[1].tc1, In[1].tc2, t );
vec3 normal_2_o = cross( tan1, vx );
Out.normal_e = normalize( mat3(ut.eye_from_object) * normal_2_o );
EmitVertex();
}
EndPrimitive();
}
#endif
#ifdef _FRAGMENT_SHADER_
#ifdef BIND_TEXUNIT
layout ( binding = BIND_TEXUNIT ) uniform sampler2D tex_unit_0;
#endif
layout ( location = 0 ) in Data_to_FS
{
vec3 normal_e;
vec4 vertex_e;
vec2 tex_coor;
} In;
layout ( location = 0 ) out vec4 out_frag_color;
void
fs_main()
{
vec4 lit_color = generic_lighting(In.vertex_e, color, In.normal_e);
if ( opt_texture == TX_None )
{
out_frag_color = lit_color;
}
else if ( opt_texture == TX_Circle )
{
float dist = length(In.tex_coor);
float angle = atan(In.tex_coor.y,In.tex_coor.x);
vec2 tc =
vec2( ( dist - ring_hole_frac ) * one_over_delta_r,
angle * dy_d_theta );
out_frag_color = lit_color * texture(tex_unit_0,tc);
}
else
{
out_frag_color = lit_color * texture(tex_unit_0,In.tex_coor);
}
}
#endif