#version 460 core

#extension GL_EXT_scalar_block_layout : enable

uint indices[6] = { 0, 1, 3, 0, 3, 2 };

vec2 verticies[4] = vec2[](
		vec2(-0.5, -0.5),
		vec2( 0.5, -0.5),
		vec2(-0.5,  0.5),
		vec2( 0.5,  0.5)
);

struct G_Rect {
	uint id;

	uint   c[4];
	float uv[4];

	float angle;
	float x, y;
	float w, h;

	float _pad0, _pad1;
};

struct Vertex {
	vec4 p;
	vec2 uv;
	uint c;
	uint pad;
};

layout(push_constant, row_major)
uniform Global {
	mat4 proj;
};

layout(binding = 0, scalar)
readonly buffer Rect {
	G_Rect rects[];
};

layout(location = 0) out vec2 frag_uv;
layout(location = 1) out vec4 frag_c;
layout(location = 2) out flat uint texid;

vec4 unorm_colour(uint c) {
	vec4 result = vec4((c >> 0) & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, (c >> 24) & 0xFF) / 255.0f;
	return result;
}

vec2 rotate2f(vec2 v, float angle) {
	float s = sin(angle);
	float c = cos(angle);

	vec2 result = vec2(c * v.x - s * v.y, s * v.x + c * v.y);
	return result;
}

void main() {
	G_Rect rect = rects[gl_InstanceIndex];
	uint   idx  = indices[gl_VertexIndex];

	vec2 p = (rotate2f(verticies[idx], rect.angle) * vec2(rect.w, rect.h)) + vec2(rect.x, rect.y);

	gl_Position = proj * vec4(p, 1.0f, 1.0f);

	frag_uv = vec2(rect.uv[(idx & 1) << 1], rect.uv[1 + (uint(idx / 2) << 1)]);
	frag_c  = unorm_colour(rect.c[idx]);
	texid   = rect.id;
}
