constructor({
        // inherited from Curtains class object
        alpha,
        antialias,
        premultipliedAlpha,
        depth,
        failIfMajorPerformanceCaveat,
        preserveDrawingBuffer,
        stencil,
        container,
        pixelRatio,
        renderingScale,
        production,

        // callbacks passed by the Curtains class object on instantiation
        onError,
        onSuccess,
        onContextLost,
        onContextRestored,
        onDisposed,
        onSceneChange,
    }) {
        this.type = "Renderer";
        // context attributes
        this.alpha = alpha;
        this.antialias = antialias;
        this.premultipliedAlpha = premultipliedAlpha;
        this.depth = depth;
        this.failIfMajorPerformanceCaveat = failIfMajorPerformanceCaveat;
        this.preserveDrawingBuffer = preserveDrawingBuffer;
        this.stencil = stencil;

        this.container = container;

        this.pixelRatio = pixelRatio;
        this._renderingScale = renderingScale;

        this.production = production;

        // callbacks
        this.onError = onError;
        this.onSuccess = onSuccess;
        this.onContextLost = onContextLost;
        this.onContextRestored = onContextRestored;
        this.onDisposed = onDisposed;

        // keep sync between Curtains objects arrays and renderer objects arrays
        this.onSceneChange = onSceneChange;

        // managing our webgl draw states
        this.initState();

        // create the canvas
        this.canvas = document.createElement("canvas");

        // set our webgl context
        const glAttributes = {
            alpha: this.alpha,
            premultipliedAlpha: this.premultipliedAlpha,
            antialias: this.antialias,
            depth: this.depth,
            failIfMajorPerformanceCaveat: this.failIfMajorPerformanceCaveat,
            preserveDrawingBuffer: this.preserveDrawingBuffer,
            stencil: this.stencil,
        };

        // try webgl2 context first
        this.gl = this.canvas.getContext("webgl2", glAttributes);
        this._isWebGL2 = !!this.gl;
        // fallback to webgl1
        if(!this.gl) {
            this.gl = this.canvas.getContext("webgl", glAttributes) || this.canvas.getContext("experimental-webgl", glAttributes);
        }

        // WebGL context could not be created
        if(!this.gl) {
            if(!this.production) throwWarning(this.type + ": WebGL context could not be created");

            this.state.isActive = false;

            if(this.onError) {
                this.onError();
            }

            return;
        }
        else if(this.onSuccess) {
            this.onSuccess();
        }

        this.initRenderer();
    }
Here we create our Renderer object
 It will create our WebGL context and handle everything that relates to it
 Will create a container, append a canvas, handle WebGL extensions, context lost/restoration events
 Will create a Scene class object that will keep tracks of all added objects
 Will also handle all global WebGL commands, like clearing scene, binding frame buffers, setting depth, blend func, etc.
 Will use a state object to handle all those commands and keep a track of what is being drawned to avoid redundant WebGL calls.

 params:
 @Curtainsparams see Curtains class object

 @onError (function): called when there has been an error while initiating the WebGL context
 @onSuccess (function): called when the WebGL context has been successfully created
 @onContextLost (function): called when the WebGL context is lost
 @onContextRestored (function): called when the WebGL context is restored
 @onSceneChange (function): called every time an object has been added/removed from the scene

 returns :
 @this: our Renderer
*