#version 330 core

uniform mat4 ProjectionMatrix;

uniform vec3 XAxis;
uniform vec3 YAxis;
uniform float global_radius;

in vec3 params[1]; // radius

out vec2 uv;
out vec2 uv2;
out vec3 wpos;
out float alpha;
out float tex_blend;
out float intensity;

layout(points) in;
layout(triangle_strip, max_vertices = 4) out;

#define EMIT_VERTEX(VTX, UV) \
	uv = (UV); \
	uv2 = (UV)*0.25 + uv_offset; \
	alpha = falloff; \
	tex_blend = blend; \
	intensity = cint; \
	wpos = VTX; \
	gl_Position = ProjectionMatrix * vec4((VTX), 1.0); \
	EmitVertex()


vec2 get_tile_offset(in float t)
{
	float tile_index = floor((1.0 - t)*4.0*4.0);
	float y = floor(tile_index / 4.0);
	float x = tile_index - y*4.0;
	return vec2(x, y) / 4.0;
}


void main()
{
	float cint = smoothstep(0.0, 0.01, params[0].y);
	float radius = params[0].x + (1.0 - cint)*0.15 + global_radius;
	if ( radius <= 0.0 ) return;

	float blend = 1.0 - smoothstep(0.0, 0.01, params[0].y);

	vec4 pos = gl_in[0].gl_Position;
	float dist = dot(vec3(0.0, 0.0, -1.0), pos.xyz ) - 1.0;
	float falloff = smoothstep(0.0, 1.0, dist)*0.5;
	if ( falloff <= 0.0 ) return;

	vec3 x = normalize( mix(vec3(1.0, 0.0, 0.0), XAxis, blend) );
	vec3 y = normalize( mix(vec3(0.0, 1.0, 0.0), YAxis, blend) );

	vec3 a = pos.xyz + (x + y)*radius;
	vec3 b = pos.xyz + (y - x)*radius;
	vec3 c = pos.xyz + (-x - y)*radius;
	vec3 d = pos.xyz + (x - y)*radius;

	vec2 uv_offset = get_tile_offset( mod(params[0].z*3.2, 4.0*4.0) );

	EMIT_VERTEX(a, vec2(1.0, 0.0));
	EMIT_VERTEX(b, vec2(0.0, 0.0));
	EMIT_VERTEX(d, vec2(1.0, 1.0));
	EMIT_VERTEX(c, vec2(0.0, 1.0));

	EndPrimitive();
}
