Alexander Rose 7 years ago
parent
commit
e14f97b1fb

+ 14 - 0
src/mol-gl/_spec/renderer.spec.ts

@@ -0,0 +1,14 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+// import createGl = require('gl');
+
+// import Renderer from '../renderer';
+
+// describe('renderer', () => {
+//     const gl = createGl(256, 256)
+//     const renderer = Renderer.create(gl, {} as any)
+// })

+ 602 - 0
src/mol-gl/controls/trackball.ts

@@ -0,0 +1,602 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+/*
+ * This code has been modified from https://github.com/mrdoob/three.js/,
+ * copyright (c) 2010-2018 three.js authors. MIT License
+ */
+
+import { map, filter, scan } from 'rxjs/operators';
+
+import { Quat, Vec2, Vec3, EPSILON } from 'mol-math/linear-algebra';
+import { clamp } from 'mol-math/interpolate';
+import InputObserver from 'mol-util/input/input-observer';
+
+export const DefaultTrackballControlsProps = {
+    position: Vec3.zero(),
+    up: Vec3.create(0, 1, 0),
+    target: Vec3.zero(),
+
+    distance: undefined as (number|undefined),
+    damping: 0.25,
+    rotateSpeed: 0.28,
+    zoomSpeed: 0.0075,
+    pinchSpeed: 0.0075,
+    panSpeed: 1.0,
+
+    staticMoving: false,
+    dynamicDampingFactor: 0.2,
+
+    minDistance: 0,
+    maxDistance: Infinity
+}
+export type TrackballControlsProps = Partial<typeof DefaultTrackballControlsProps>
+
+const enum STATE {
+    NONE = - 1,
+    ROTATE = 0,
+    ZOOM = 1,
+    PAN = 2,
+    TOUCH_ROTATE = 3,
+    TOUCH_ZOOM_PAN = 4
+}
+
+interface Object {
+    position: Vec3,
+    up: Vec3,
+}
+
+interface Screen {
+    left: number
+    top: number
+    width: number
+    height: number
+}
+
+interface TrackballControls {
+    update: () => void
+    copyInto: (positionOut: Vec3, directionOut: Vec3, upOut: Vec3) => void
+
+    position: Vec3
+    direction: Vec3
+    up: Vec3
+    target: Vec3
+
+    distance: number
+    damping: number
+    rotateSpeed: number
+    zoomSpeed: number
+    pinchSpeed: number
+    panSpeed: number
+}
+
+namespace TrackballControls {
+    export function create (element: Element, object: Object, props: TrackballControlsProps = {}): TrackballControls {
+        const p = { ...DefaultTrackballControlsProps, ...props }
+
+        const screen: Screen = { left: 0, top: 0, width: 0, height: 0 }
+
+        let { rotateSpeed, zoomSpeed, panSpeed } = p
+        let { staticMoving, dynamicDampingFactor } = p
+        let { minDistance, maxDistance } = p
+
+        // internals
+        const target = Vec3.zero()
+        const lastPosition = Vec3.zero()
+
+        let _state = STATE.NONE
+        let _prevState = STATE.NONE
+
+        const _eye = Vec3.zero()
+
+        const _movePrev = Vec2.zero()
+        const _moveCurr = Vec2.zero()
+
+        const _lastAxis = Vec3.zero()
+        let _lastAngle = 0
+
+        const _zoomStart = Vec2.zero()
+        const _zoomEnd = Vec2.zero()
+
+        let _touchZoomDistanceStart = 0
+        let _touchZoomDistanceEnd = 0
+
+        const _panStart = Vec2.zero()
+        const _panEnd = Vec2.zero()
+
+        // for reset
+        const target0 = Vec3.clone(target)
+        const position0 = Vec3.clone(object.position)
+        const up0 = Vec3.clone(object.up)
+
+        // methods
+        function handleResize () {
+            if ( element instanceof Document ) {
+                screen.left = 0;
+                screen.top = 0;
+                screen.width = window.innerWidth;
+                screen.height = window.innerHeight;
+            } else {
+                const box = element.getBoundingClientRect();
+                // adjustments come from similar code in the jquery offset() function
+                const d = element.ownerDocument.documentElement;
+                screen.left = box.left + window.pageXOffset - d.clientLeft;
+                screen.top = box.top + window.pageYOffset - d.clientTop;
+                screen.width = box.width;
+                screen.height = box.height;
+            }
+        }
+
+        const mouseOnScreenVec2 = Vec2.zero()
+        function getMouseOnScreen(pageX: number, pageY: number) {
+            Vec2.set(
+                mouseOnScreenVec2,
+                (pageX - screen.left) / screen.width,
+                (pageY - screen.top) / screen.height
+            );
+            return mouseOnScreenVec2;
+        }
+
+        const mouseOnCircleVec2 = Vec2.zero()
+        function getMouseOnCircle(pageX: number, pageY: number) {
+            Vec2.set(
+                mouseOnCircleVec2,
+                ((pageX - screen.width * 0.5 - screen.left) / (screen.width * 0.5)),
+                ((screen.height + 2 * (screen.top - pageY)) / screen.width) // screen.width intentional
+            );
+            return mouseOnCircleVec2;
+        }
+
+        const rotAxis = Vec3.zero()
+        const rotQuat = Quat.zero()
+        const rotEyeDir = Vec3.zero()
+        const rotObjUpDir = Vec3.zero()
+        const rotObjSideDir = Vec3.zero()
+        const rotMoveDir = Vec3.zero()
+
+        function rotateCamera() {
+            Vec3.set(rotMoveDir, _moveCurr[0] - _movePrev[0], _moveCurr[1] - _movePrev[1], 0);
+            let angle = Vec3.magnitude(rotMoveDir);
+
+            if (angle) {
+                Vec3.copy(_eye, object.position)
+                Vec3.sub(_eye, _eye, target)
+
+                Vec3.normalize(rotEyeDir, Vec3.copy(rotEyeDir, _eye))
+                Vec3.normalize(rotObjUpDir, Vec3.copy(rotObjUpDir, object.up))
+                Vec3.normalize(rotObjSideDir, Vec3.cross(rotObjSideDir, rotObjSideDir, rotEyeDir))
+
+                Vec3.setMagnitude(rotObjUpDir, rotObjUpDir, _moveCurr[1] - _movePrev[1])
+                Vec3.setMagnitude(rotObjSideDir, rotObjSideDir, _moveCurr[0] - _movePrev[0])
+
+                Vec3.add(rotMoveDir, Vec3.copy(rotMoveDir, rotObjUpDir), rotObjSideDir)
+
+                Vec3.normalize(rotAxis, Vec3.cross(rotAxis, rotMoveDir, _eye))
+
+                angle *= rotateSpeed;
+                Quat.setAxisAngle(rotQuat, rotAxis, angle )
+
+                Vec3.transformQuat(_eye, _eye, rotQuat)
+                Vec3.transformQuat(object.up, object.up, rotQuat)
+
+                Vec3.copy(_lastAxis, rotAxis)
+                _lastAngle = angle;
+            } else if (!staticMoving && _lastAngle) {
+
+                _lastAngle *= Math.sqrt(1.0 - dynamicDampingFactor);
+                Vec3.sub(_eye, Vec3.copy(_eye, object.position), target)
+                Quat.setAxisAngle(rotQuat, _lastAxis, _lastAngle)
+
+                Vec3.transformQuat(_eye, _eye, rotQuat)
+                Vec3.transformQuat(object.up, object.up, rotQuat)
+            }
+
+            Vec2.copy(_movePrev, _moveCurr)
+        }
+
+
+        function zoomCamera () {
+            if (_state === STATE.TOUCH_ZOOM_PAN) {
+                const factor = _touchZoomDistanceStart / _touchZoomDistanceEnd
+                _touchZoomDistanceStart = _touchZoomDistanceEnd;
+                Vec3.scale(_eye, _eye, factor)
+            } else {
+                const factor = 1.0 + ( _zoomEnd[1] - _zoomStart[1] ) * zoomSpeed
+                if (factor !== 1.0 && factor > 0.0) {
+                    Vec3.scale(_eye, _eye, factor)
+                }
+
+                if (staticMoving) {
+                    Vec2.copy(_zoomStart, _zoomEnd)
+                } else {
+                    _zoomStart[1] += ( _zoomEnd[1] - _zoomStart[1] ) * dynamicDampingFactor
+                }
+            }
+        }
+
+        const panMouseChange = Vec2.zero()
+        const panObjUp = Vec3.zero()
+        const panOffset = Vec3.zero()
+
+        function panCamera() {
+            Vec2.sub(panMouseChange, Vec2.copy(panMouseChange, _panEnd), _panStart)
+
+            if ( Vec2.squaredMagnitude(panMouseChange)) {
+
+                mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
+
+                pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
+                pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) );
+
+                _this.object.position.add( pan );
+                _this.target.add( pan );
+
+                if ( _this.staticMoving ) {
+
+                    _panStart.copy( _panEnd );
+
+                } else {
+
+                    _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
+
+                }
+            }
+        }
+
+        this.checkDistances = function () {
+
+            if ( ! _this.noZoom || ! _this.noPan ) {
+
+                if ( _eye.lengthSq() > _this.maxDistance * _this.maxDistance ) {
+
+                    _this.object.position.addVectors( _this.target, _eye.setLength( _this.maxDistance ) );
+                    _zoomStart.copy( _zoomEnd );
+
+                }
+
+                if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {
+
+                    _this.object.position.addVectors( _this.target, _eye.setLength( _this.minDistance ) );
+                    _zoomStart.copy( _zoomEnd );
+
+                }
+
+            }
+
+        };
+
+        this.update = function () {
+
+            _eye.subVectors( _this.object.position, _this.target );
+
+            if ( ! _this.noRotate ) {
+
+                _this.rotateCamera();
+
+            }
+
+            if ( ! _this.noZoom ) {
+
+                _this.zoomCamera();
+
+            }
+
+            if ( ! _this.noPan ) {
+
+                _this.panCamera();
+
+            }
+
+            _this.object.position.addVectors( _this.target, _eye );
+
+            _this.checkDistances();
+
+            _this.object.lookAt( _this.target );
+
+            if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) {
+
+                _this.dispatchEvent( changeEvent );
+
+                lastPosition.copy( _this.object.position );
+
+            }
+
+        };
+
+        this.reset = function () {
+
+            _state = STATE.NONE;
+            _prevState = STATE.NONE;
+
+            _this.target.copy( _this.target0 );
+            _this.object.position.copy( _this.position0 );
+            _this.object.up.copy( _this.up0 );
+
+            _eye.subVectors( _this.object.position, _this.target );
+
+            _this.object.lookAt( _this.target );
+
+            _this.dispatchEvent( changeEvent );
+
+            lastPosition.copy( _this.object.position );
+
+        };
+
+        // listeners
+
+        function keydown( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            window.removeEventListener( 'keydown', keydown );
+
+            _prevState = _state;
+
+            if ( _state !== STATE.NONE ) {
+
+                return;
+
+            } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && ! _this.noRotate ) {
+
+                _state = STATE.ROTATE;
+
+            } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && ! _this.noZoom ) {
+
+                _state = STATE.ZOOM;
+
+            } else if ( event.keyCode === _this.keys[ STATE.PAN ] && ! _this.noPan ) {
+
+                _state = STATE.PAN;
+
+            }
+
+        }
+
+        function keyup( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            _state = _prevState;
+
+            window.addEventListener( 'keydown', keydown, false );
+
+        }
+
+        function mousedown( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            event.preventDefault();
+            event.stopPropagation();
+
+            if ( _state === STATE.NONE ) {
+
+                _state = event.button;
+
+            }
+
+            if ( _state === STATE.ROTATE && ! _this.noRotate ) {
+
+                _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
+                _movePrev.copy( _moveCurr );
+
+            } else if ( _state === STATE.ZOOM && ! _this.noZoom ) {
+
+                _zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
+                _zoomEnd.copy( _zoomStart );
+
+            } else if ( _state === STATE.PAN && ! _this.noPan ) {
+
+                _panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
+                _panEnd.copy( _panStart );
+
+            }
+
+            document.addEventListener( 'mousemove', mousemove, false );
+            document.addEventListener( 'mouseup', mouseup, false );
+
+            _this.dispatchEvent( startEvent );
+
+        }
+
+        function mousemove( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            event.preventDefault();
+            event.stopPropagation();
+
+            if ( _state === STATE.ROTATE && ! _this.noRotate ) {
+
+                _movePrev.copy( _moveCurr );
+                _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
+
+            } else if ( _state === STATE.ZOOM && ! _this.noZoom ) {
+
+                _zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
+
+            } else if ( _state === STATE.PAN && ! _this.noPan ) {
+
+                _panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
+
+            }
+
+        }
+
+        function mouseup( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            event.preventDefault();
+            event.stopPropagation();
+
+            _state = STATE.NONE;
+
+            document.removeEventListener( 'mousemove', mousemove );
+            document.removeEventListener( 'mouseup', mouseup );
+            _this.dispatchEvent( endEvent );
+
+        }
+
+        function mousewheel( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            if ( _this.noZoom === true ) return;
+
+            event.preventDefault();
+            event.stopPropagation();
+
+            switch ( event.deltaMode ) {
+
+                case 2:
+                    // Zoom in pages
+                    _zoomStart.y -= event.deltaY * 0.025;
+                    break;
+
+                case 1:
+                    // Zoom in lines
+                    _zoomStart.y -= event.deltaY * 0.01;
+                    break;
+
+                default:
+                    // undefined, 0, assume pixels
+                    _zoomStart.y -= event.deltaY * 0.00025;
+                    break;
+
+            }
+
+            _this.dispatchEvent( startEvent );
+            _this.dispatchEvent( endEvent );
+
+        }
+
+        function touchstart( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            switch ( event.touches.length ) {
+
+                case 1:
+                    _state = STATE.TOUCH_ROTATE;
+                    _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
+                    _movePrev.copy( _moveCurr );
+                    break;
+
+                default: // 2 or more
+                    _state = STATE.TOUCH_ZOOM_PAN;
+                    var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
+                    var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
+                    _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
+
+                    var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
+                    var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
+                    _panStart.copy( getMouseOnScreen( x, y ) );
+                    _panEnd.copy( _panStart );
+                    break;
+
+            }
+
+            _this.dispatchEvent( startEvent );
+
+        }
+
+        function touchmove( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            event.preventDefault();
+            event.stopPropagation();
+
+            switch ( event.touches.length ) {
+
+                case 1:
+                    _movePrev.copy( _moveCurr );
+                    _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
+                    break;
+
+                default: // 2 or more
+                    var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
+                    var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
+                    _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
+
+                    var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2;
+                    var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2;
+                    _panEnd.copy( getMouseOnScreen( x, y ) );
+                    break;
+
+            }
+
+        }
+
+        function touchend( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            switch ( event.touches.length ) {
+
+                case 0:
+                    _state = STATE.NONE;
+                    break;
+
+                case 1:
+                    _state = STATE.TOUCH_ROTATE;
+                    _moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) );
+                    _movePrev.copy( _moveCurr );
+                    break;
+
+            }
+
+            _this.dispatchEvent( endEvent );
+
+        }
+
+        function contextmenu( event ) {
+
+            if ( _this.enabled === false ) return;
+
+            event.preventDefault();
+
+        }
+
+        this.dispose = function() {
+
+            this.domElement.removeEventListener( 'contextmenu', contextmenu, false );
+            this.domElement.removeEventListener( 'mousedown', mousedown, false );
+            this.domElement.removeEventListener( 'wheel', mousewheel, false );
+
+            this.domElement.removeEventListener( 'touchstart', touchstart, false );
+            this.domElement.removeEventListener( 'touchend', touchend, false );
+            this.domElement.removeEventListener( 'touchmove', touchmove, false );
+
+            document.removeEventListener( 'mousemove', mousemove, false );
+            document.removeEventListener( 'mouseup', mouseup, false );
+
+            window.removeEventListener( 'keydown', keydown, false );
+            window.removeEventListener( 'keyup', keyup, false );
+
+        };
+
+        this.domElement.addEventListener( 'contextmenu', contextmenu, false );
+        this.domElement.addEventListener( 'mousedown', mousedown, false );
+        this.domElement.addEventListener( 'wheel', mousewheel, false );
+
+        this.domElement.addEventListener( 'touchstart', touchstart, false );
+        this.domElement.addEventListener( 'touchend', touchend, false );
+        this.domElement.addEventListener( 'touchmove', touchmove, false );
+
+        window.addEventListener( 'keydown', keydown, false );
+        window.addEventListener( 'keyup', keyup, false );
+
+        this.handleResize();
+
+        // force an update at start
+        this.update();
+
+    }
+}
+
+export default TrackballControls

+ 904 - 0
src/mol-gl/gl.d.ts

@@ -0,0 +1,904 @@
+// Type definitions for gl 4.0.4
+// Project: headless-gl
+// Definitions by: Ivan Perevezentsev (https://github.com/ip)
+
+declare module 'gl' {
+
+    /*~ Note that ES6 modules cannot directly export callable functions.
+    *~ This file should be imported using the CommonJS-style:
+    *~   import x = require('someLibrary');
+    *~
+    *~ Refer to the documentation to understand common
+    *~ workarounds for this limitation of ES6 modules.
+    */
+
+    /*~ This declaration specifies that the function
+    *~ is the exported object from the file
+    */
+    export = createWebglContext;
+
+    function createWebglContext(
+      width: number,
+      height: number,
+      options?: WebGLContextAttributes): WebGLRenderingContext;
+  }
+
+  interface WebGLContextAttributes {
+    failIfMajorPerformanceCaveat?: boolean;
+    alpha?: boolean;
+    antialias?: boolean;
+    depth?: boolean;
+    premultipliedAlpha?: boolean;
+    preserveDrawingBuffer?: boolean;
+    stencil?: boolean;
+  }
+
+  interface WEBGL_compressed_texture_s3tc {
+      readonly COMPRESSED_RGB_S3TC_DXT1_EXT: number;
+      readonly COMPRESSED_RGBA_S3TC_DXT1_EXT: number;
+      readonly COMPRESSED_RGBA_S3TC_DXT3_EXT: number;
+      readonly COMPRESSED_RGBA_S3TC_DXT5_EXT: number;
+  }
+
+  declare var WEBGL_compressed_texture_s3tc: {
+      prototype: WEBGL_compressed_texture_s3tc;
+      new(): WEBGL_compressed_texture_s3tc;
+      readonly COMPRESSED_RGB_S3TC_DXT1_EXT: number;
+      readonly COMPRESSED_RGBA_S3TC_DXT1_EXT: number;
+      readonly COMPRESSED_RGBA_S3TC_DXT3_EXT: number;
+      readonly COMPRESSED_RGBA_S3TC_DXT5_EXT: number;
+  };
+
+  interface WEBGL_debug_renderer_info {
+      readonly UNMASKED_RENDERER_WEBGL: number;
+      readonly UNMASKED_VENDOR_WEBGL: number;
+  }
+
+  declare var WEBGL_debug_renderer_info: {
+      prototype: WEBGL_debug_renderer_info;
+      new(): WEBGL_debug_renderer_info;
+      readonly UNMASKED_RENDERER_WEBGL: number;
+      readonly UNMASKED_VENDOR_WEBGL: number;
+  };
+
+  interface WEBGL_depth_texture {
+      readonly UNSIGNED_INT_24_8_WEBGL: number;
+  }
+
+  declare var WEBGL_depth_texture: {
+      prototype: WEBGL_depth_texture;
+      new(): WEBGL_depth_texture;
+      readonly UNSIGNED_INT_24_8_WEBGL: number;
+  };
+
+  interface WebGLActiveInfo {
+      readonly name: string;
+      readonly size: number;
+      readonly type: number;
+  }
+
+  declare var WebGLActiveInfo: {
+      prototype: WebGLActiveInfo;
+      new(): WebGLActiveInfo;
+  };
+
+  interface WebGLBuffer extends WebGLObject {
+  }
+
+  declare var WebGLBuffer: {
+      prototype: WebGLBuffer;
+      new(): WebGLBuffer;
+  };
+
+  // interface WebGLContextEvent extends Event {
+  //     readonly statusMessage: string;
+  // }
+
+  interface WebGLFramebuffer extends WebGLObject {
+  }
+
+  declare var WebGLFramebuffer: {
+      prototype: WebGLFramebuffer;
+      new(): WebGLFramebuffer;
+  };
+
+  interface WebGLObject {
+  }
+
+  declare var WebGLObject: {
+      prototype: WebGLObject;
+      new(): WebGLObject;
+  };
+
+  interface WebGLProgram extends WebGLObject {
+  }
+
+  declare var WebGLProgram: {
+      prototype: WebGLProgram;
+      new(): WebGLProgram;
+  };
+
+  interface WebGLRenderbuffer extends WebGLObject {
+  }
+
+  declare var WebGLRenderbuffer: {
+      prototype: WebGLRenderbuffer;
+      new(): WebGLRenderbuffer;
+  };
+
+  interface WebGLRenderingContext {
+      readonly drawingBufferHeight: number;
+      readonly drawingBufferWidth: number;
+      activeTexture(texture: number): void;
+      attachShader(program: WebGLProgram | null, shader: WebGLShader | null): void;
+      bindAttribLocation(program: WebGLProgram | null, index: number, name: string): void;
+      bindBuffer(target: number, buffer: WebGLBuffer | null): void;
+      bindFramebuffer(target: number, framebuffer: WebGLFramebuffer | null): void;
+      bindRenderbuffer(target: number, renderbuffer: WebGLRenderbuffer | null): void;
+      bindTexture(target: number, texture: WebGLTexture | null): void;
+      blendColor(red: number, green: number, blue: number, alpha: number): void;
+      blendEquation(mode: number): void;
+      blendEquationSeparate(modeRGB: number, modeAlpha: number): void;
+      blendFunc(sfactor: number, dfactor: number): void;
+      blendFuncSeparate(srcRGB: number, dstRGB: number, srcAlpha: number, dstAlpha: number): void;
+      bufferData(target: number, size: number | ArrayBufferView | ArrayBuffer, usage: number): void;
+      bufferSubData(target: number, offset: number, data: ArrayBufferView | ArrayBuffer): void;
+      checkFramebufferStatus(target: number): number;
+      clear(mask: number): void;
+      clearColor(red: number, green: number, blue: number, alpha: number): void;
+      clearDepth(depth: number): void;
+      clearStencil(s: number): void;
+      colorMask(red: boolean, green: boolean, blue: boolean, alpha: boolean): void;
+      compileShader(shader: WebGLShader | null): void;
+      compressedTexImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, data: ArrayBufferView): void;
+      compressedTexSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, data: ArrayBufferView): void;
+      copyTexImage2D(target: number, level: number, internalformat: number, x: number, y: number, width: number, height: number, border: number): void;
+      copyTexSubImage2D(target: number, level: number, xoffset: number, yoffset: number, x: number, y: number, width: number, height: number): void;
+      createBuffer(): WebGLBuffer | null;
+      createFramebuffer(): WebGLFramebuffer | null;
+      createProgram(): WebGLProgram | null;
+      createRenderbuffer(): WebGLRenderbuffer | null;
+      createShader(type: number): WebGLShader | null;
+      createTexture(): WebGLTexture | null;
+      cullFace(mode: number): void;
+      deleteBuffer(buffer: WebGLBuffer | null): void;
+      deleteFramebuffer(framebuffer: WebGLFramebuffer | null): void;
+      deleteProgram(program: WebGLProgram | null): void;
+      deleteRenderbuffer(renderbuffer: WebGLRenderbuffer | null): void;
+      deleteShader(shader: WebGLShader | null): void;
+      deleteTexture(texture: WebGLTexture | null): void;
+      depthFunc(func: number): void;
+      depthMask(flag: boolean): void;
+      depthRange(zNear: number, zFar: number): void;
+      detachShader(program: WebGLProgram | null, shader: WebGLShader | null): void;
+      disable(cap: number): void;
+      disableVertexAttribArray(index: number): void;
+      drawArrays(mode: number, first: number, count: number): void;
+      drawElements(mode: number, count: number, type: number, offset: number): void;
+      enable(cap: number): void;
+      enableVertexAttribArray(index: number): void;
+      finish(): void;
+      flush(): void;
+      framebufferRenderbuffer(target: number, attachment: number, renderbuffertarget: number, renderbuffer: WebGLRenderbuffer | null): void;
+      framebufferTexture2D(target: number, attachment: number, textarget: number, texture: WebGLTexture | null, level: number): void;
+      frontFace(mode: number): void;
+      generateMipmap(target: number): void;
+      getActiveAttrib(program: WebGLProgram | null, index: number): WebGLActiveInfo | null;
+      getActiveUniform(program: WebGLProgram | null, index: number): WebGLActiveInfo | null;
+      getAttachedShaders(program: WebGLProgram | null): WebGLShader[] | null;
+      getAttribLocation(program: WebGLProgram | null, name: string): number;
+      getBufferParameter(target: number, pname: number): any;
+      getContextAttributes(): WebGLContextAttributes;
+      getError(): number;
+      getExtension(name: string): any;
+      getFramebufferAttachmentParameter(target: number, attachment: number, pname: number): any;
+      getParameter(pname: number): any;
+      getProgramInfoLog(program: WebGLProgram | null): string | null;
+      getProgramParameter(program: WebGLProgram | null, pname: number): any;
+      getRenderbufferParameter(target: number, pname: number): any;
+      getShaderInfoLog(shader: WebGLShader | null): string | null;
+      getShaderParameter(shader: WebGLShader | null, pname: number): any;
+      getShaderPrecisionFormat(shadertype: number, precisiontype: number): WebGLShaderPrecisionFormat | null;
+      getShaderSource(shader: WebGLShader | null): string | null;
+      getSupportedExtensions(): string[] | null;
+      getTexParameter(target: number, pname: number): any;
+      getUniform(program: WebGLProgram | null, location: WebGLUniformLocation | null): any;
+      getUniformLocation(program: WebGLProgram | null, name: string): WebGLUniformLocation | null;
+      getVertexAttrib(index: number, pname: number): any;
+      getVertexAttribOffset(index: number, pname: number): number;
+      hint(target: number, mode: number): void;
+      isBuffer(buffer: WebGLBuffer | null): boolean;
+      isContextLost(): boolean;
+      isEnabled(cap: number): boolean;
+      isFramebuffer(framebuffer: WebGLFramebuffer | null): boolean;
+      isProgram(program: WebGLProgram | null): boolean;
+      isRenderbuffer(renderbuffer: WebGLRenderbuffer | null): boolean;
+      isShader(shader: WebGLShader | null): boolean;
+      isTexture(texture: WebGLTexture | null): boolean;
+      lineWidth(width: number): void;
+      linkProgram(program: WebGLProgram | null): void;
+      pixelStorei(pname: number, param: number | boolean): void;
+      polygonOffset(factor: number, units: number): void;
+      readPixels(x: number, y: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView | null): void;
+      renderbufferStorage(target: number, internalformat: number, width: number, height: number): void;
+      sampleCoverage(value: number, invert: boolean): void;
+      scissor(x: number, y: number, width: number, height: number): void;
+      shaderSource(shader: WebGLShader | null, source: string): void;
+      stencilFunc(func: number, ref: number, mask: number): void;
+      stencilFuncSeparate(face: number, func: number, ref: number, mask: number): void;
+      stencilMask(mask: number): void;
+      stencilMaskSeparate(face: number, mask: number): void;
+      stencilOp(fail: number, zfail: number, zpass: number): void;
+      stencilOpSeparate(face: number, fail: number, zfail: number, zpass: number): void;
+      texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ArrayBufferView | null): void;
+      // texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
+      texParameterf(target: number, pname: number, param: number): void;
+      texParameteri(target: number, pname: number, param: number): void;
+      texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView | null): void;
+      // texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels: ImageBitmap | ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void;
+      uniform1f(location: WebGLUniformLocation | null, x: number): void;
+      uniform1fv(location: WebGLUniformLocation, v: Float32Array | number[]): void;
+      uniform1i(location: WebGLUniformLocation | null, x: number): void;
+      uniform1iv(location: WebGLUniformLocation, v: Int32Array | number[]): void;
+      uniform2f(location: WebGLUniformLocation | null, x: number, y: number): void;
+      uniform2fv(location: WebGLUniformLocation, v: Float32Array | number[]): void;
+      uniform2i(location: WebGLUniformLocation | null, x: number, y: number): void;
+      uniform2iv(location: WebGLUniformLocation, v: Int32Array | number[]): void;
+      uniform3f(location: WebGLUniformLocation | null, x: number, y: number, z: number): void;
+      uniform3fv(location: WebGLUniformLocation, v: Float32Array | number[]): void;
+      uniform3i(location: WebGLUniformLocation | null, x: number, y: number, z: number): void;
+      uniform3iv(location: WebGLUniformLocation, v: Int32Array | number[]): void;
+      uniform4f(location: WebGLUniformLocation | null, x: number, y: number, z: number, w: number): void;
+      uniform4fv(location: WebGLUniformLocation, v: Float32Array | number[]): void;
+      uniform4i(location: WebGLUniformLocation | null, x: number, y: number, z: number, w: number): void;
+      uniform4iv(location: WebGLUniformLocation, v: Int32Array | number[]): void;
+      uniformMatrix2fv(location: WebGLUniformLocation, transpose: boolean, value: Float32Array | number[]): void;
+      uniformMatrix3fv(location: WebGLUniformLocation, transpose: boolean, value: Float32Array | number[]): void;
+      uniformMatrix4fv(location: WebGLUniformLocation, transpose: boolean, value: Float32Array | number[]): void;
+      useProgram(program: WebGLProgram | null): void;
+      validateProgram(program: WebGLProgram | null): void;
+      vertexAttrib1f(indx: number, x: number): void;
+      vertexAttrib1fv(indx: number, values: Float32Array | number[]): void;
+      vertexAttrib2f(indx: number, x: number, y: number): void;
+      vertexAttrib2fv(indx: number, values: Float32Array | number[]): void;
+      vertexAttrib3f(indx: number, x: number, y: number, z: number): void;
+      vertexAttrib3fv(indx: number, values: Float32Array | number[]): void;
+      vertexAttrib4f(indx: number, x: number, y: number, z: number, w: number): void;
+      vertexAttrib4fv(indx: number, values: Float32Array | number[]): void;
+      vertexAttribPointer(indx: number, size: number, type: number, normalized: boolean, stride: number, offset: number): void;
+      viewport(x: number, y: number, width: number, height: number): void;
+      readonly ACTIVE_ATTRIBUTES: number;
+      readonly ACTIVE_TEXTURE: number;
+      readonly ACTIVE_UNIFORMS: number;
+      readonly ALIASED_LINE_WIDTH_RANGE: number;
+      readonly ALIASED_POINT_SIZE_RANGE: number;
+      readonly ALPHA: number;
+      readonly ALPHA_BITS: number;
+      readonly ALWAYS: number;
+      readonly ARRAY_BUFFER: number;
+      readonly ARRAY_BUFFER_BINDING: number;
+      readonly ATTACHED_SHADERS: number;
+      readonly BACK: number;
+      readonly BLEND: number;
+      readonly BLEND_COLOR: number;
+      readonly BLEND_DST_ALPHA: number;
+      readonly BLEND_DST_RGB: number;
+      readonly BLEND_EQUATION: number;
+      readonly BLEND_EQUATION_ALPHA: number;
+      readonly BLEND_EQUATION_RGB: number;
+      readonly BLEND_SRC_ALPHA: number;
+      readonly BLEND_SRC_RGB: number;
+      readonly BLUE_BITS: number;
+      readonly BOOL: number;
+      readonly BOOL_VEC2: number;
+      readonly BOOL_VEC3: number;
+      readonly BOOL_VEC4: number;
+      readonly BROWSER_DEFAULT_WEBGL: number;
+      readonly BUFFER_SIZE: number;
+      readonly BUFFER_USAGE: number;
+      readonly BYTE: number;
+      readonly CCW: number;
+      readonly CLAMP_TO_EDGE: number;
+      readonly COLOR_ATTACHMENT0: number;
+      readonly COLOR_BUFFER_BIT: number;
+      readonly COLOR_CLEAR_VALUE: number;
+      readonly COLOR_WRITEMASK: number;
+      readonly COMPILE_STATUS: number;
+      readonly COMPRESSED_TEXTURE_FORMATS: number;
+      readonly CONSTANT_ALPHA: number;
+      readonly CONSTANT_COLOR: number;
+      readonly CONTEXT_LOST_WEBGL: number;
+      readonly CULL_FACE: number;
+      readonly CULL_FACE_MODE: number;
+      readonly CURRENT_PROGRAM: number;
+      readonly CURRENT_VERTEX_ATTRIB: number;
+      readonly CW: number;
+      readonly DECR: number;
+      readonly DECR_WRAP: number;
+      readonly DELETE_STATUS: number;
+      readonly DEPTH_ATTACHMENT: number;
+      readonly DEPTH_BITS: number;
+      readonly DEPTH_BUFFER_BIT: number;
+      readonly DEPTH_CLEAR_VALUE: number;
+      readonly DEPTH_COMPONENT: number;
+      readonly DEPTH_COMPONENT16: number;
+      readonly DEPTH_FUNC: number;
+      readonly DEPTH_RANGE: number;
+      readonly DEPTH_STENCIL: number;
+      readonly DEPTH_STENCIL_ATTACHMENT: number;
+      readonly DEPTH_TEST: number;
+      readonly DEPTH_WRITEMASK: number;
+      readonly DITHER: number;
+      readonly DONT_CARE: number;
+      readonly DST_ALPHA: number;
+      readonly DST_COLOR: number;
+      readonly DYNAMIC_DRAW: number;
+      readonly ELEMENT_ARRAY_BUFFER: number;
+      readonly ELEMENT_ARRAY_BUFFER_BINDING: number;
+      readonly EQUAL: number;
+      readonly FASTEST: number;
+      readonly FLOAT: number;
+      readonly FLOAT_MAT2: number;
+      readonly FLOAT_MAT3: number;
+      readonly FLOAT_MAT4: number;
+      readonly FLOAT_VEC2: number;
+      readonly FLOAT_VEC3: number;
+      readonly FLOAT_VEC4: number;
+      readonly FRAGMENT_SHADER: number;
+      readonly FRAMEBUFFER: number;
+      readonly FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: number;
+      readonly FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: number;
+      readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: number;
+      readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: number;
+      readonly FRAMEBUFFER_BINDING: number;
+      readonly FRAMEBUFFER_COMPLETE: number;
+      readonly FRAMEBUFFER_INCOMPLETE_ATTACHMENT: number;
+      readonly FRAMEBUFFER_INCOMPLETE_DIMENSIONS: number;
+      readonly FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: number;
+      readonly FRAMEBUFFER_UNSUPPORTED: number;
+      readonly FRONT: number;
+      readonly FRONT_AND_BACK: number;
+      readonly FRONT_FACE: number;
+      readonly FUNC_ADD: number;
+      readonly FUNC_REVERSE_SUBTRACT: number;
+      readonly FUNC_SUBTRACT: number;
+      readonly GENERATE_MIPMAP_HINT: number;
+      readonly GEQUAL: number;
+      readonly GREATER: number;
+      readonly GREEN_BITS: number;
+      readonly HIGH_FLOAT: number;
+      readonly HIGH_INT: number;
+      readonly IMPLEMENTATION_COLOR_READ_FORMAT: number;
+      readonly IMPLEMENTATION_COLOR_READ_TYPE: number;
+      readonly INCR: number;
+      readonly INCR_WRAP: number;
+      readonly INT: number;
+      readonly INT_VEC2: number;
+      readonly INT_VEC3: number;
+      readonly INT_VEC4: number;
+      readonly INVALID_ENUM: number;
+      readonly INVALID_FRAMEBUFFER_OPERATION: number;
+      readonly INVALID_OPERATION: number;
+      readonly INVALID_VALUE: number;
+      readonly INVERT: number;
+      readonly KEEP: number;
+      readonly LEQUAL: number;
+      readonly LESS: number;
+      readonly LINE_LOOP: number;
+      readonly LINE_STRIP: number;
+      readonly LINE_WIDTH: number;
+      readonly LINEAR: number;
+      readonly LINEAR_MIPMAP_LINEAR: number;
+      readonly LINEAR_MIPMAP_NEAREST: number;
+      readonly LINES: number;
+      readonly LINK_STATUS: number;
+      readonly LOW_FLOAT: number;
+      readonly LOW_INT: number;
+      readonly LUMINANCE: number;
+      readonly LUMINANCE_ALPHA: number;
+      readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: number;
+      readonly MAX_CUBE_MAP_TEXTURE_SIZE: number;
+      readonly MAX_FRAGMENT_UNIFORM_VECTORS: number;
+      readonly MAX_RENDERBUFFER_SIZE: number;
+      readonly MAX_TEXTURE_IMAGE_UNITS: number;
+      readonly MAX_TEXTURE_SIZE: number;
+      readonly MAX_VARYING_VECTORS: number;
+      readonly MAX_VERTEX_ATTRIBS: number;
+      readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: number;
+      readonly MAX_VERTEX_UNIFORM_VECTORS: number;
+      readonly MAX_VIEWPORT_DIMS: number;
+      readonly MEDIUM_FLOAT: number;
+      readonly MEDIUM_INT: number;
+      readonly MIRRORED_REPEAT: number;
+      readonly NEAREST: number;
+      readonly NEAREST_MIPMAP_LINEAR: number;
+      readonly NEAREST_MIPMAP_NEAREST: number;
+      readonly NEVER: number;
+      readonly NICEST: number;
+      readonly NO_ERROR: number;
+      readonly NONE: number;
+      readonly NOTEQUAL: number;
+      readonly ONE: number;
+      readonly ONE_MINUS_CONSTANT_ALPHA: number;
+      readonly ONE_MINUS_CONSTANT_COLOR: number;
+      readonly ONE_MINUS_DST_ALPHA: number;
+      readonly ONE_MINUS_DST_COLOR: number;
+      readonly ONE_MINUS_SRC_ALPHA: number;
+      readonly ONE_MINUS_SRC_COLOR: number;
+      readonly OUT_OF_MEMORY: number;
+      readonly PACK_ALIGNMENT: number;
+      readonly POINTS: number;
+      readonly POLYGON_OFFSET_FACTOR: number;
+      readonly POLYGON_OFFSET_FILL: number;
+      readonly POLYGON_OFFSET_UNITS: number;
+      readonly RED_BITS: number;
+      readonly RENDERBUFFER: number;
+      readonly RENDERBUFFER_ALPHA_SIZE: number;
+      readonly RENDERBUFFER_BINDING: number;
+      readonly RENDERBUFFER_BLUE_SIZE: number;
+      readonly RENDERBUFFER_DEPTH_SIZE: number;
+      readonly RENDERBUFFER_GREEN_SIZE: number;
+      readonly RENDERBUFFER_HEIGHT: number;
+      readonly RENDERBUFFER_INTERNAL_FORMAT: number;
+      readonly RENDERBUFFER_RED_SIZE: number;
+      readonly RENDERBUFFER_STENCIL_SIZE: number;
+      readonly RENDERBUFFER_WIDTH: number;
+      readonly RENDERER: number;
+      readonly REPEAT: number;
+      readonly REPLACE: number;
+      readonly RGB: number;
+      readonly RGB5_A1: number;
+      readonly RGB565: number;
+      readonly RGBA: number;
+      readonly RGBA4: number;
+      readonly SAMPLE_ALPHA_TO_COVERAGE: number;
+      readonly SAMPLE_BUFFERS: number;
+      readonly SAMPLE_COVERAGE: number;
+      readonly SAMPLE_COVERAGE_INVERT: number;
+      readonly SAMPLE_COVERAGE_VALUE: number;
+      readonly SAMPLER_2D: number;
+      readonly SAMPLER_CUBE: number;
+      readonly SAMPLES: number;
+      readonly SCISSOR_BOX: number;
+      readonly SCISSOR_TEST: number;
+      readonly SHADER_TYPE: number;
+      readonly SHADING_LANGUAGE_VERSION: number;
+      readonly SHORT: number;
+      readonly SRC_ALPHA: number;
+      readonly SRC_ALPHA_SATURATE: number;
+      readonly SRC_COLOR: number;
+      readonly STATIC_DRAW: number;
+      readonly STENCIL_ATTACHMENT: number;
+      readonly STENCIL_BACK_FAIL: number;
+      readonly STENCIL_BACK_FUNC: number;
+      readonly STENCIL_BACK_PASS_DEPTH_FAIL: number;
+      readonly STENCIL_BACK_PASS_DEPTH_PASS: number;
+      readonly STENCIL_BACK_REF: number;
+      readonly STENCIL_BACK_VALUE_MASK: number;
+      readonly STENCIL_BACK_WRITEMASK: number;
+      readonly STENCIL_BITS: number;
+      readonly STENCIL_BUFFER_BIT: number;
+      readonly STENCIL_CLEAR_VALUE: number;
+      readonly STENCIL_FAIL: number;
+      readonly STENCIL_FUNC: number;
+      readonly STENCIL_INDEX: number;
+      readonly STENCIL_INDEX8: number;
+      readonly STENCIL_PASS_DEPTH_FAIL: number;
+      readonly STENCIL_PASS_DEPTH_PASS: number;
+      readonly STENCIL_REF: number;
+      readonly STENCIL_TEST: number;
+      readonly STENCIL_VALUE_MASK: number;
+      readonly STENCIL_WRITEMASK: number;
+      readonly STREAM_DRAW: number;
+      readonly SUBPIXEL_BITS: number;
+      readonly TEXTURE: number;
+      readonly TEXTURE_2D: number;
+      readonly TEXTURE_BINDING_2D: number;
+      readonly TEXTURE_BINDING_CUBE_MAP: number;
+      readonly TEXTURE_CUBE_MAP: number;
+      readonly TEXTURE_CUBE_MAP_NEGATIVE_X: number;
+      readonly TEXTURE_CUBE_MAP_NEGATIVE_Y: number;
+      readonly TEXTURE_CUBE_MAP_NEGATIVE_Z: number;
+      readonly TEXTURE_CUBE_MAP_POSITIVE_X: number;
+      readonly TEXTURE_CUBE_MAP_POSITIVE_Y: number;
+      readonly TEXTURE_CUBE_MAP_POSITIVE_Z: number;
+      readonly TEXTURE_MAG_FILTER: number;
+      readonly TEXTURE_MIN_FILTER: number;
+      readonly TEXTURE_WRAP_S: number;
+      readonly TEXTURE_WRAP_T: number;
+      readonly TEXTURE0: number;
+      readonly TEXTURE1: number;
+      readonly TEXTURE10: number;
+      readonly TEXTURE11: number;
+      readonly TEXTURE12: number;
+      readonly TEXTURE13: number;
+      readonly TEXTURE14: number;
+      readonly TEXTURE15: number;
+      readonly TEXTURE16: number;
+      readonly TEXTURE17: number;
+      readonly TEXTURE18: number;
+      readonly TEXTURE19: number;
+      readonly TEXTURE2: number;
+      readonly TEXTURE20: number;
+      readonly TEXTURE21: number;
+      readonly TEXTURE22: number;
+      readonly TEXTURE23: number;
+      readonly TEXTURE24: number;
+      readonly TEXTURE25: number;
+      readonly TEXTURE26: number;
+      readonly TEXTURE27: number;
+      readonly TEXTURE28: number;
+      readonly TEXTURE29: number;
+      readonly TEXTURE3: number;
+      readonly TEXTURE30: number;
+      readonly TEXTURE31: number;
+      readonly TEXTURE4: number;
+      readonly TEXTURE5: number;
+      readonly TEXTURE6: number;
+      readonly TEXTURE7: number;
+      readonly TEXTURE8: number;
+      readonly TEXTURE9: number;
+      readonly TRIANGLE_FAN: number;
+      readonly TRIANGLE_STRIP: number;
+      readonly TRIANGLES: number;
+      readonly UNPACK_ALIGNMENT: number;
+      readonly UNPACK_COLORSPACE_CONVERSION_WEBGL: number;
+      readonly UNPACK_FLIP_Y_WEBGL: number;
+      readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: number;
+      readonly UNSIGNED_BYTE: number;
+      readonly UNSIGNED_INT: number;
+      readonly UNSIGNED_SHORT: number;
+      readonly UNSIGNED_SHORT_4_4_4_4: number;
+      readonly UNSIGNED_SHORT_5_5_5_1: number;
+      readonly UNSIGNED_SHORT_5_6_5: number;
+      readonly VALIDATE_STATUS: number;
+      readonly VENDOR: number;
+      readonly VERSION: number;
+      readonly VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: number;
+      readonly VERTEX_ATTRIB_ARRAY_ENABLED: number;
+      readonly VERTEX_ATTRIB_ARRAY_NORMALIZED: number;
+      readonly VERTEX_ATTRIB_ARRAY_POINTER: number;
+      readonly VERTEX_ATTRIB_ARRAY_SIZE: number;
+      readonly VERTEX_ATTRIB_ARRAY_STRIDE: number;
+      readonly VERTEX_ATTRIB_ARRAY_TYPE: number;
+      readonly VERTEX_SHADER: number;
+      readonly VIEWPORT: number;
+      readonly ZERO: number;
+  }
+
+  declare var WebGLRenderingContext: {
+      prototype: WebGLRenderingContext;
+      new(): WebGLRenderingContext;
+      readonly ACTIVE_ATTRIBUTES: number;
+      readonly ACTIVE_TEXTURE: number;
+      readonly ACTIVE_UNIFORMS: number;
+      readonly ALIASED_LINE_WIDTH_RANGE: number;
+      readonly ALIASED_POINT_SIZE_RANGE: number;
+      readonly ALPHA: number;
+      readonly ALPHA_BITS: number;
+      readonly ALWAYS: number;
+      readonly ARRAY_BUFFER: number;
+      readonly ARRAY_BUFFER_BINDING: number;
+      readonly ATTACHED_SHADERS: number;
+      readonly BACK: number;
+      readonly BLEND: number;
+      readonly BLEND_COLOR: number;
+      readonly BLEND_DST_ALPHA: number;
+      readonly BLEND_DST_RGB: number;
+      readonly BLEND_EQUATION: number;
+      readonly BLEND_EQUATION_ALPHA: number;
+      readonly BLEND_EQUATION_RGB: number;
+      readonly BLEND_SRC_ALPHA: number;
+      readonly BLEND_SRC_RGB: number;
+      readonly BLUE_BITS: number;
+      readonly BOOL: number;
+      readonly BOOL_VEC2: number;
+      readonly BOOL_VEC3: number;
+      readonly BOOL_VEC4: number;
+      readonly BROWSER_DEFAULT_WEBGL: number;
+      readonly BUFFER_SIZE: number;
+      readonly BUFFER_USAGE: number;
+      readonly BYTE: number;
+      readonly CCW: number;
+      readonly CLAMP_TO_EDGE: number;
+      readonly COLOR_ATTACHMENT0: number;
+      readonly COLOR_BUFFER_BIT: number;
+      readonly COLOR_CLEAR_VALUE: number;
+      readonly COLOR_WRITEMASK: number;
+      readonly COMPILE_STATUS: number;
+      readonly COMPRESSED_TEXTURE_FORMATS: number;
+      readonly CONSTANT_ALPHA: number;
+      readonly CONSTANT_COLOR: number;
+      readonly CONTEXT_LOST_WEBGL: number;
+      readonly CULL_FACE: number;
+      readonly CULL_FACE_MODE: number;
+      readonly CURRENT_PROGRAM: number;
+      readonly CURRENT_VERTEX_ATTRIB: number;
+      readonly CW: number;
+      readonly DECR: number;
+      readonly DECR_WRAP: number;
+      readonly DELETE_STATUS: number;
+      readonly DEPTH_ATTACHMENT: number;
+      readonly DEPTH_BITS: number;
+      readonly DEPTH_BUFFER_BIT: number;
+      readonly DEPTH_CLEAR_VALUE: number;
+      readonly DEPTH_COMPONENT: number;
+      readonly DEPTH_COMPONENT16: number;
+      readonly DEPTH_FUNC: number;
+      readonly DEPTH_RANGE: number;
+      readonly DEPTH_STENCIL: number;
+      readonly DEPTH_STENCIL_ATTACHMENT: number;
+      readonly DEPTH_TEST: number;
+      readonly DEPTH_WRITEMASK: number;
+      readonly DITHER: number;
+      readonly DONT_CARE: number;
+      readonly DST_ALPHA: number;
+      readonly DST_COLOR: number;
+      readonly DYNAMIC_DRAW: number;
+      readonly ELEMENT_ARRAY_BUFFER: number;
+      readonly ELEMENT_ARRAY_BUFFER_BINDING: number;
+      readonly EQUAL: number;
+      readonly FASTEST: number;
+      readonly FLOAT: number;
+      readonly FLOAT_MAT2: number;
+      readonly FLOAT_MAT3: number;
+      readonly FLOAT_MAT4: number;
+      readonly FLOAT_VEC2: number;
+      readonly FLOAT_VEC3: number;
+      readonly FLOAT_VEC4: number;
+      readonly FRAGMENT_SHADER: number;
+      readonly FRAMEBUFFER: number;
+      readonly FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: number;
+      readonly FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: number;
+      readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: number;
+      readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: number;
+      readonly FRAMEBUFFER_BINDING: number;
+      readonly FRAMEBUFFER_COMPLETE: number;
+      readonly FRAMEBUFFER_INCOMPLETE_ATTACHMENT: number;
+      readonly FRAMEBUFFER_INCOMPLETE_DIMENSIONS: number;
+      readonly FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: number;
+      readonly FRAMEBUFFER_UNSUPPORTED: number;
+      readonly FRONT: number;
+      readonly FRONT_AND_BACK: number;
+      readonly FRONT_FACE: number;
+      readonly FUNC_ADD: number;
+      readonly FUNC_REVERSE_SUBTRACT: number;
+      readonly FUNC_SUBTRACT: number;
+      readonly GENERATE_MIPMAP_HINT: number;
+      readonly GEQUAL: number;
+      readonly GREATER: number;
+      readonly GREEN_BITS: number;
+      readonly HIGH_FLOAT: number;
+      readonly HIGH_INT: number;
+      readonly IMPLEMENTATION_COLOR_READ_FORMAT: number;
+      readonly IMPLEMENTATION_COLOR_READ_TYPE: number;
+      readonly INCR: number;
+      readonly INCR_WRAP: number;
+      readonly INT: number;
+      readonly INT_VEC2: number;
+      readonly INT_VEC3: number;
+      readonly INT_VEC4: number;
+      readonly INVALID_ENUM: number;
+      readonly INVALID_FRAMEBUFFER_OPERATION: number;
+      readonly INVALID_OPERATION: number;
+      readonly INVALID_VALUE: number;
+      readonly INVERT: number;
+      readonly KEEP: number;
+      readonly LEQUAL: number;
+      readonly LESS: number;
+      readonly LINE_LOOP: number;
+      readonly LINE_STRIP: number;
+      readonly LINE_WIDTH: number;
+      readonly LINEAR: number;
+      readonly LINEAR_MIPMAP_LINEAR: number;
+      readonly LINEAR_MIPMAP_NEAREST: number;
+      readonly LINES: number;
+      readonly LINK_STATUS: number;
+      readonly LOW_FLOAT: number;
+      readonly LOW_INT: number;
+      readonly LUMINANCE: number;
+      readonly LUMINANCE_ALPHA: number;
+      readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: number;
+      readonly MAX_CUBE_MAP_TEXTURE_SIZE: number;
+      readonly MAX_FRAGMENT_UNIFORM_VECTORS: number;
+      readonly MAX_RENDERBUFFER_SIZE: number;
+      readonly MAX_TEXTURE_IMAGE_UNITS: number;
+      readonly MAX_TEXTURE_SIZE: number;
+      readonly MAX_VARYING_VECTORS: number;
+      readonly MAX_VERTEX_ATTRIBS: number;
+      readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: number;
+      readonly MAX_VERTEX_UNIFORM_VECTORS: number;
+      readonly MAX_VIEWPORT_DIMS: number;
+      readonly MEDIUM_FLOAT: number;
+      readonly MEDIUM_INT: number;
+      readonly MIRRORED_REPEAT: number;
+      readonly NEAREST: number;
+      readonly NEAREST_MIPMAP_LINEAR: number;
+      readonly NEAREST_MIPMAP_NEAREST: number;
+      readonly NEVER: number;
+      readonly NICEST: number;
+      readonly NO_ERROR: number;
+      readonly NONE: number;
+      readonly NOTEQUAL: number;
+      readonly ONE: number;
+      readonly ONE_MINUS_CONSTANT_ALPHA: number;
+      readonly ONE_MINUS_CONSTANT_COLOR: number;
+      readonly ONE_MINUS_DST_ALPHA: number;
+      readonly ONE_MINUS_DST_COLOR: number;
+      readonly ONE_MINUS_SRC_ALPHA: number;
+      readonly ONE_MINUS_SRC_COLOR: number;
+      readonly OUT_OF_MEMORY: number;
+      readonly PACK_ALIGNMENT: number;
+      readonly POINTS: number;
+      readonly POLYGON_OFFSET_FACTOR: number;
+      readonly POLYGON_OFFSET_FILL: number;
+      readonly POLYGON_OFFSET_UNITS: number;
+      readonly RED_BITS: number;
+      readonly RENDERBUFFER: number;
+      readonly RENDERBUFFER_ALPHA_SIZE: number;
+      readonly RENDERBUFFER_BINDING: number;
+      readonly RENDERBUFFER_BLUE_SIZE: number;
+      readonly RENDERBUFFER_DEPTH_SIZE: number;
+      readonly RENDERBUFFER_GREEN_SIZE: number;
+      readonly RENDERBUFFER_HEIGHT: number;
+      readonly RENDERBUFFER_INTERNAL_FORMAT: number;
+      readonly RENDERBUFFER_RED_SIZE: number;
+      readonly RENDERBUFFER_STENCIL_SIZE: number;
+      readonly RENDERBUFFER_WIDTH: number;
+      readonly RENDERER: number;
+      readonly REPEAT: number;
+      readonly REPLACE: number;
+      readonly RGB: number;
+      readonly RGB5_A1: number;
+      readonly RGB565: number;
+      readonly RGBA: number;
+      readonly RGBA4: number;
+      readonly SAMPLE_ALPHA_TO_COVERAGE: number;
+      readonly SAMPLE_BUFFERS: number;
+      readonly SAMPLE_COVERAGE: number;
+      readonly SAMPLE_COVERAGE_INVERT: number;
+      readonly SAMPLE_COVERAGE_VALUE: number;
+      readonly SAMPLER_2D: number;
+      readonly SAMPLER_CUBE: number;
+      readonly SAMPLES: number;
+      readonly SCISSOR_BOX: number;
+      readonly SCISSOR_TEST: number;
+      readonly SHADER_TYPE: number;
+      readonly SHADING_LANGUAGE_VERSION: number;
+      readonly SHORT: number;
+      readonly SRC_ALPHA: number;
+      readonly SRC_ALPHA_SATURATE: number;
+      readonly SRC_COLOR: number;
+      readonly STATIC_DRAW: number;
+      readonly STENCIL_ATTACHMENT: number;
+      readonly STENCIL_BACK_FAIL: number;
+      readonly STENCIL_BACK_FUNC: number;
+      readonly STENCIL_BACK_PASS_DEPTH_FAIL: number;
+      readonly STENCIL_BACK_PASS_DEPTH_PASS: number;
+      readonly STENCIL_BACK_REF: number;
+      readonly STENCIL_BACK_VALUE_MASK: number;
+      readonly STENCIL_BACK_WRITEMASK: number;
+      readonly STENCIL_BITS: number;
+      readonly STENCIL_BUFFER_BIT: number;
+      readonly STENCIL_CLEAR_VALUE: number;
+      readonly STENCIL_FAIL: number;
+      readonly STENCIL_FUNC: number;
+      readonly STENCIL_INDEX: number;
+      readonly STENCIL_INDEX8: number;
+      readonly STENCIL_PASS_DEPTH_FAIL: number;
+      readonly STENCIL_PASS_DEPTH_PASS: number;
+      readonly STENCIL_REF: number;
+      readonly STENCIL_TEST: number;
+      readonly STENCIL_VALUE_MASK: number;
+      readonly STENCIL_WRITEMASK: number;
+      readonly STREAM_DRAW: number;
+      readonly SUBPIXEL_BITS: number;
+      readonly TEXTURE: number;
+      readonly TEXTURE_2D: number;
+      readonly TEXTURE_BINDING_2D: number;
+      readonly TEXTURE_BINDING_CUBE_MAP: number;
+      readonly TEXTURE_CUBE_MAP: number;
+      readonly TEXTURE_CUBE_MAP_NEGATIVE_X: number;
+      readonly TEXTURE_CUBE_MAP_NEGATIVE_Y: number;
+      readonly TEXTURE_CUBE_MAP_NEGATIVE_Z: number;
+      readonly TEXTURE_CUBE_MAP_POSITIVE_X: number;
+      readonly TEXTURE_CUBE_MAP_POSITIVE_Y: number;
+      readonly TEXTURE_CUBE_MAP_POSITIVE_Z: number;
+      readonly TEXTURE_MAG_FILTER: number;
+      readonly TEXTURE_MIN_FILTER: number;
+      readonly TEXTURE_WRAP_S: number;
+      readonly TEXTURE_WRAP_T: number;
+      readonly TEXTURE0: number;
+      readonly TEXTURE1: number;
+      readonly TEXTURE10: number;
+      readonly TEXTURE11: number;
+      readonly TEXTURE12: number;
+      readonly TEXTURE13: number;
+      readonly TEXTURE14: number;
+      readonly TEXTURE15: number;
+      readonly TEXTURE16: number;
+      readonly TEXTURE17: number;
+      readonly TEXTURE18: number;
+      readonly TEXTURE19: number;
+      readonly TEXTURE2: number;
+      readonly TEXTURE20: number;
+      readonly TEXTURE21: number;
+      readonly TEXTURE22: number;
+      readonly TEXTURE23: number;
+      readonly TEXTURE24: number;
+      readonly TEXTURE25: number;
+      readonly TEXTURE26: number;
+      readonly TEXTURE27: number;
+      readonly TEXTURE28: number;
+      readonly TEXTURE29: number;
+      readonly TEXTURE3: number;
+      readonly TEXTURE30: number;
+      readonly TEXTURE31: number;
+      readonly TEXTURE4: number;
+      readonly TEXTURE5: number;
+      readonly TEXTURE6: number;
+      readonly TEXTURE7: number;
+      readonly TEXTURE8: number;
+      readonly TEXTURE9: number;
+      readonly TRIANGLE_FAN: number;
+      readonly TRIANGLE_STRIP: number;
+      readonly TRIANGLES: number;
+      readonly UNPACK_ALIGNMENT: number;
+      readonly UNPACK_COLORSPACE_CONVERSION_WEBGL: number;
+      readonly UNPACK_FLIP_Y_WEBGL: number;
+      readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: number;
+      readonly UNSIGNED_BYTE: number;
+      readonly UNSIGNED_INT: number;
+      readonly UNSIGNED_SHORT: number;
+      readonly UNSIGNED_SHORT_4_4_4_4: number;
+      readonly UNSIGNED_SHORT_5_5_5_1: number;
+      readonly UNSIGNED_SHORT_5_6_5: number;
+      readonly VALIDATE_STATUS: number;
+      readonly VENDOR: number;
+      readonly VERSION: number;
+      readonly VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: number;
+      readonly VERTEX_ATTRIB_ARRAY_ENABLED: number;
+      readonly VERTEX_ATTRIB_ARRAY_NORMALIZED: number;
+      readonly VERTEX_ATTRIB_ARRAY_POINTER: number;
+      readonly VERTEX_ATTRIB_ARRAY_SIZE: number;
+      readonly VERTEX_ATTRIB_ARRAY_STRIDE: number;
+      readonly VERTEX_ATTRIB_ARRAY_TYPE: number;
+      readonly VERTEX_SHADER: number;
+      readonly VIEWPORT: number;
+      readonly ZERO: number;
+  };
+
+  interface WebGLShader extends WebGLObject {
+  }
+
+  declare var WebGLShader: {
+      prototype: WebGLShader;
+      new(): WebGLShader;
+  };
+
+  interface WebGLShaderPrecisionFormat {
+      readonly precision: number;
+      readonly rangeMax: number;
+      readonly rangeMin: number;
+  }
+
+  declare var WebGLShaderPrecisionFormat: {
+      prototype: WebGLShaderPrecisionFormat;
+      new(): WebGLShaderPrecisionFormat;
+  };
+
+  interface WebGLTexture extends WebGLObject {
+  }
+
+  declare var WebGLTexture: {
+      prototype: WebGLTexture;
+      new(): WebGLTexture;
+  };
+
+  interface WebGLUniformLocation {
+  }
+
+  declare var WebGLUniformLocation: {
+      prototype: WebGLUniformLocation;
+      new(): WebGLUniformLocation;
+  };

+ 18 - 0
src/mol-math/linear-algebra/3d/vec2.ts

@@ -69,6 +69,12 @@ namespace Vec2 {
         return out;
     }
 
+    export function sub(out: Vec2, a: Vec2, b: Vec2) {
+        out[0] = a[0] - b[0];
+        out[1] = a[1] - b[1];
+        return out;
+    }
+
     export function distance(a: Vec2, b: Vec2) {
         const x = b[0] - a[0],
             y = b[1] - a[1];
@@ -80,6 +86,18 @@ namespace Vec2 {
             y = b[1] - a[1];
         return x * x + y * y;
     }
+
+    export function magnitude(a: Vec2) {
+        const x = a[0],
+            y = a[1];
+        return Math.sqrt(x * x + y * y);
+    }
+
+    export function squaredMagnitude(a: Vec2) {
+        const x = a[0],
+            y = a[1];
+        return x * x + y * y;
+    }
 }
 
 export default Vec2

+ 4 - 0
src/mol-math/linear-algebra/3d/vec3.ts

@@ -136,6 +136,10 @@ namespace Vec3 {
         return x * x + y * y + z * z;
     }
 
+    export function setMagnitude(out: Vec3, a: Vec3, l: number) {
+        return Vec3.scale(out, Vec3.normalize(out, a), l)
+    }
+
     export function normalize(out: Vec3, a: Vec3) {
         const x = a[0],
             y = a[1],