#version 460 core
struct PositionData {
    float x;
    float y;
    float z;
};

struct UvData {
    float u;
    float v;
};

struct NormalData {
    float x;
    float y;
    float z;
};

layout (binding = 0, std430) restrict readonly buffer _positions {
    PositionData pos_data[];
};

layout (binding = 1, std430) restrict readonly buffer _uvs {
    UvData uv_data[];
};

layout (binding = 2, std430) restrict readonly buffer _normals {
    NormalData norm_data[];
};

vec4 getPosition(int index) {
    return vec4(
        pos_data[index].x,
        pos_data[index].y,
        pos_data[index].z,
        1
    );
}

vec2 getUv(int index) {
    return vec2(
        uv_data[index].u,
        uv_data[index].v
    );
}

vec3 getNormal(int index) {
    return vec3(
        norm_data[index].x,
        norm_data[index].y,
        norm_data[index].z
    );
}

uniform mat4 u_model_matrix;
uniform mat4 u_normal_matrix;

layout (binding = 0, std140) uniform SharedMatrices {
    mat4 projection;
    mat4 cam_matrix;
};

out vec2 v_texcoord;
out vec3 v_normal;
out vec3 v_position;

void main() {
    gl_Position = projection * cam_matrix * u_model_matrix * getPosition(gl_VertexID);
    v_texcoord = getUv(gl_VertexID);
    v_normal = mat3(u_normal_matrix) * getNormal(gl_VertexID);
    v_position = vec3(u_model_matrix * getPosition(gl_VertexID));
}
