function createTexture(gl, options, callback) {
  callback = callback || noop;
  options = options || defaults.textureOptions;
  var tex = gl.createTexture();
  var target = options.target || TEXTURE_2D;
  var width = options.width || 1;
  var height = options.height || 1;
  var internalFormat = options.internalFormat || RGBA;
  gl.bindTexture(target, tex);
  if (target === TEXTURE_CUBE_MAP) {
    // this should have been the default for cubemaps :(
    gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE);
    gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE);
  }
  var src = options.src;
  if (src) {
    if (typeof src === "function") {
      src = src(gl, options);
    }
    if (typeof src === "string") {
      loadTextureFromUrl(gl, tex, options, callback);
    } else if (isArrayBuffer(src) || Array.isArray(src) && (typeof src[0] === 'number' || Array.isArray(src[0]) || isArrayBuffer(src[0]))) {
      var dimensions = setTextureFromArray(gl, tex, src, options);
      width = dimensions.width;
      height = dimensions.height;
    } else if (Array.isArray(src) && (typeof src[0] === 'string' || isTexImageSource(src[0]))) {
      if (target === TEXTURE_CUBE_MAP) {
        loadCubemapFromUrls(gl, tex, options, callback);
      } else {
        loadSlicesFromUrls(gl, tex, options, callback);
      }
    } else {
      // if (isTexImageSource(src))
      setTextureFromElement(gl, tex, src, options);
      width = src.width;
      height = src.height;
    }
  } else {
    setEmptyTexture(gl, tex, options);
  }
  if (shouldAutomaticallySetTextureFilteringForSize(options)) {
    setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);
  }
  setTextureParameters(gl, tex, options);
  return tex;
}
Creates a texture based on the options passed in.

See {@link module:twgl.TextureOptions}

Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES
UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS

UNPACK_FLIP_Y_WEBGL, UNPACK_PREMULTIPLY_ALPHA_WEBGL, UNPACK_COLORSPACE_CONVERSION_WEBGL
are left as is though you can pass in options for flipY, premultiplyAlpha, and colorspaceConversion
to override them.

As for the behavior of these settings

```js
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
t1 = twgl.createTexture({src: someImage }); // flipped
t2 = twgl.createTexture({src: someImage, flipY: true }); // flipped
t3 = twgl.createTexture({src: someImage, flipY: false }); // not flipped
t4 = twgl.createTexture({src: someImage }); // flipped
```

* t1 is flipped because UNPACK_FLIP_Y_WEBGL is true
* t2 is flipped because it was requested
* t3 is not flipped because it was requested
* t4 is flipped because UNPACK_FLIP_Y_WEBGL has been restored to true

@param {WebGLRenderingContext} gl the WebGLRenderingContext
@param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.
@param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture.
@return {WebGLTexture} the created texture.
@memberOf module:twgl/textures