#version 330

uniform mat4 modelviewProjection;

layout (location = 0) in float altitude;
layout (location = 1) in uint biome;
layout (location = 2) in uvec2 chunk;

out vec2 texCoord;
flat out uint v_biome;

const uint TILE_SIZE = 4u;
const uint TILES_PER_CHUNK_ROW = 250u;
const uint TRIANGLES_PER_CHUNK_ROW = TILES_PER_CHUNK_ROW * 2u + 2u;

void main() {
    uint u_gl_vertex_id = uint(gl_VertexID) % (TILES_PER_CHUNK_ROW * (TILES_PER_CHUNK_ROW * 2u + 2u) + 3u);
    if(u_gl_vertex_id <= 1u)
    {
        u_gl_vertex_id = 0u;
    }
    else
    {
        u_gl_vertex_id -= 2u;
    }
    uint index_mod_triangles_per_chunk_row = u_gl_vertex_id % TRIANGLES_PER_CHUNK_ROW;
    uint index_div_triangles_per_chunk_row = u_gl_vertex_id / TRIANGLES_PER_CHUNK_ROW;
    uint index_div_triangles_per_chunk_row_mod_2 = index_div_triangles_per_chunk_row % 2u;
    uint index_mod_triangles_per_chunk_row_div_2 = index_mod_triangles_per_chunk_row / 2u;

    uint x = index_div_triangles_per_chunk_row_mod_2 == 0u ? index_mod_triangles_per_chunk_row_div_2 : TILES_PER_CHUNK_ROW - index_mod_triangles_per_chunk_row_div_2;
    uint z = index_div_triangles_per_chunk_row + u_gl_vertex_id % 2u;

    switch (u_gl_vertex_id % 4u) {
    case 0u:
        texCoord = vec2(index_div_triangles_per_chunk_row_mod_2, 0);
        break;
    case 1u:
        texCoord = vec2(index_div_triangles_per_chunk_row_mod_2, 1);
        break;
    case 2u:
        texCoord = vec2(1u - index_div_triangles_per_chunk_row_mod_2, 0);
        break;
    default: // case 3u
        texCoord = vec2(1u - index_div_triangles_per_chunk_row_mod_2, 1);
        break;
    }
    v_biome = biome;

    x *= TILE_SIZE;
    z *= TILE_SIZE;

    uint cx = chunk.x - chunk.x % 1000u;
    uint cy = chunk.y - chunk.y % 1000u;

    x += cx;
    z += cy;

    gl_Position = modelviewProjection * vec4(x, z, altitude, 1.0);
}