dispose() {
        if(!this.gl) return;

        this.state.isActive = false;

        // be sure to delete all planes
        while(this.planes.length > 0) {
            this.removePlane(this.planes[0]);
        }

        // we need to delete the shader passes also
        while(this.shaderPasses.length > 0) {
            this.removeShaderPass(this.shaderPasses[0]);
        }

        // finally we need to delete the render targets
        while(this.renderTargets.length > 0) {
            this.removeRenderTarget(this.renderTargets[0]);
        }

        // wait for all planes to be deleted before stopping everything
        let disposeQueue = this.nextRender.add(() => {
            if(this.planes.length === 0 && this.shaderPasses.length === 0 && this.renderTargets.length === 0) {
                // clear from callback queue
                disposeQueue.keep = false;

                this.deletePrograms();

                // clear the buffer to clean scene
                this.clear();

                this.canvas.removeEventListener("webgllost", this._contextLostHandler, false);
                this.canvas.removeEventListener("webglrestored", this._contextRestoredHandler, false);

                // lose context
                if(this.gl && this.extensions['WEBGL_lose_context']) {
                    this.extensions['WEBGL_lose_context'].loseContext();
                }

                // clear canvas state
                this.canvas.width = this.canvas.width;

                this.gl = null;

                // remove canvas from DOM
                this.container.removeChild(this.canvas);

                this.container = null;
                this.canvas = null;

                this.onDisposed && this.onDisposed();
            }
        }, true);
    }
Dispose our WebGL context and all its objects
*