
struct Mesh
{
    GLenum primitives;
    GLuint vao;
    unsigned count;
};

Mesh make_grid( const int n= 10 )
{
    std::vector<Point> positions;
    std::vector<Color> colors;
    
    // grille
    for(int x= 0; x < n; x++)
    {
        float px= float(x) - float(n-1)/2;
        
        colors.push_back( White() ); positions.push_back( { px, 0, - float(n-1)/2 } ); 
        colors.push_back( White() ); positions.push_back( { px, 0, float(n-1)/2 } );
    }
    
    for(int z= 0; z < n; z++)
    {
        float pz= float(z) - float(n-1)/2;
        
        colors.push_back( White() ); positions.push_back( { - float(n-1)/2, 0, pz }); 
        colors.push_back( White() ); positions.push_back( { float(n-1)/2, 0, pz } ); 
    }
    
    // axes XYZ
    colors.push_back( Red() ); positions.push_back( { 0, .1, 0 } );
    colors.push_back( Red() ); positions.push_back( {1, .1, 0 } );
    
    colors.push_back( Green() ); positions.push_back( { 0, .1, 0 } );
    colors.push_back( Green() ); positions.push_back( { 0, 1, 0 } );
    
    colors.push_back( Blue() ); positions.push_back( { 0, .1, 0 } );
    colors.push_back( Blue() ); positions.push_back( { 0, .1, 1 } );
    
    glLineWidth(2);
    return { GL_LINES, create_buffers( positions, {}, {}, {}, colors ), positions.size() };
}

Mesh make_frame( )
{
    std::vector<Point> positions;
    std::vector<Color> colors;
    
    colors.push_back( Red() ); positions.push_back( { 0, .1, 0 } );
    colors.push_back( Red() ); positions.push_back( {2, .1, 0 } );
    
    colors.push_back( Green() ); positions.push_back( { 0, .1, 0 } );
    colors.push_back( Green() ); positions.push_back( { 0, 2, 0 } );
    
    colors.push_back( Blue() ); positions.push_back( { 0, .1, 0 } );
    colors.push_back( Blue() ); positions.push_back( { 0, .1, 2 } );
    
    glLineWidth(2);
    return { GL_LINES, create_buffers( positions, {}, {}, {}, colors ), positions.size() };
}

Mesh make_camera( )
{
    std::vector<Point> positions;
    std::vector<Color> colors;
    
    colors.push_back( Yellow() ); positions.push_back( { 0,0,0 } );
    colors.push_back( Yellow() ); positions.push_back( { -0.5, -0.5, -1 } );
    colors.push_back( Yellow() ); positions.push_back( { 0,0,0 } );
    colors.push_back( Yellow() ); positions.push_back( { -0.5, 0.5, -1 } );
    colors.push_back( Yellow() ); positions.push_back( { 0,0,0 } );
    colors.push_back( Yellow() ); positions.push_back( { 0.5, 0.5, -1 } );
    colors.push_back( Yellow() ); positions.push_back( { 0,0,0 } );
    colors.push_back( Yellow() ); positions.push_back( { 0.5, -0.5, -1 } );
    
    colors.push_back( Yellow() ); positions.push_back( { -0.5, -0.5, -1 } );
    colors.push_back( Yellow() ); positions.push_back( { -0.5, 0.5, -1 } );
    
    colors.push_back( Yellow() ); positions.push_back( { -0.5, 0.5, -1 } );
    colors.push_back( Yellow() ); positions.push_back( { 0.5, 0.5, -1 } );
    
    colors.push_back( Yellow() ); positions.push_back( { 0.5, 0.5, -1 } );
    colors.push_back( Yellow() ); positions.push_back( { 0.5, -0.5, -1 } );
    
    colors.push_back( Yellow() ); positions.push_back( { 0.5, -0.5, -1 } );
    colors.push_back( Yellow() ); positions.push_back( { -0.5, -0.5, -1 } );
    
    // axes XYZ
    colors.push_back( Red() ); positions.push_back( { 0, .1, 0 } );
    colors.push_back( Red() ); positions.push_back( {1, .1, 0 } );
    
    colors.push_back( Green() ); positions.push_back( { 0, .1, 0 } );
    colors.push_back( Green() ); positions.push_back( { 0, 1, 0 } );
    
    colors.push_back( Blue() ); positions.push_back( { 0, .1, 0 } );
    colors.push_back( Blue() ); positions.push_back( { 0, .1, 1 } );
    
    glLineWidth(2);
    return { GL_LINES, create_buffers( positions, {}, {}, {}, colors ), positions.size() };
}

