constructor(renderer, {
        program = null,
        width = 1,
        height = 1,
    } = {}) {
        this.type = "Geometry";
        if(!renderer || renderer.type !== "Renderer") {
            throwError(this.type + ": Renderer not passed as first argument", renderer);
        }
        else if(!renderer.gl) {
            throwError(this.type + ": Renderer WebGL context is undefined", renderer);

            // return if no gl context
            return;
        }
        this.renderer = renderer;
        this.gl = this.renderer.gl;

        // unique plane buffers id based on width and height
        // used to get a geometry from cache
        this.definition = {
            id: width * height + width,
            width: width,
            height: height,
        };

        this.setDefaultAttributes();
        this.setVerticesUVs();
    }
Geometry class handles attributes, VertexArrayObjects (if available) and vertices/UVs set up

 params:
 @renderer (Renderer class object): our renderer class object

 @program (object): our mesh's Program (see Program class object)
 @width (int): number of vertices along width
 @height (int): number of vertices along height
 @id (int): an integer based on geometry's width and height and used to avoid redundant buffer binding calls

 returns:
 @this: our newly created Geometry
*