function setUniforms(setters, values) {  // eslint-disable-line
    var actualSetters = setters.uniformSetters || setters;
    var numArgs = arguments.length;
    for (var andx = 1; andx < numArgs; ++andx) {
      var vals = arguments[andx];
      if (Array.isArray(vals)) {
        var numValues = vals.length;
        for (var ii = 0; ii < numValues; ++ii) {
          setUniforms(actualSetters, vals[ii]);
        }
      } else {
        for (var name in vals) {
          var setter = actualSetters[name];
          if (setter) {
            setter(vals[name]);
          }
        }
      }
    }
  }
Set uniforms and binds related textures.

example:

    var programInfo = createProgramInfo(
        gl, ["some-vs", "some-fs"]);

    var tex1 = gl.createTexture();
    var tex2 = gl.createTexture();

    ... assume we setup the textures with data ...

    var uniforms = {
      u_someSampler: tex1,
      u_someOtherSampler: tex2,
      u_someColor: [1,0,0,1],
      u_somePosition: [0,1,1],
      u_someMatrix: [
        1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        0,0,0,0,
      ],
    };

    gl.useProgram(program);

This will automatically bind the textures AND set the
uniforms.

    twgl.setUniforms(programInfo, uniforms);

For the example above it is equivalent to

    var texUnit = 0;
    gl.activeTexture(gl.TEXTURE0 + texUnit);
    gl.bindTexture(gl.TEXTURE_2D, tex1);
    gl.uniform1i(u_someSamplerLocation, texUnit++);
    gl.activeTexture(gl.TEXTURE0 + texUnit);
    gl.bindTexture(gl.TEXTURE_2D, tex2);
    gl.uniform1i(u_someSamplerLocation, texUnit++);
    gl.uniform4fv(u_someColorLocation, [1, 0, 0, 1]);
    gl.uniform3fv(u_somePositionLocation, [0, 1, 1]);
    gl.uniformMatrix4fv(u_someMatrix, false, [
        1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        0,0,0,0,
      ]);

Note it is perfectly reasonable to call `setUniforms` multiple times. For example

    var uniforms = {
      u_someSampler: tex1,
      u_someOtherSampler: tex2,
    };

    var moreUniforms {
      u_someColor: [1,0,0,1],
      u_somePosition: [0,1,1],
      u_someMatrix: [
        1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        0,0,0,0,
      ],
    };

    twgl.setUniforms(programInfo, uniforms);
    twgl.setUniforms(programInfo, moreUniforms);

@param {(module:twgl.ProgramInfo|Object.<string, function>)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from
       `createUniformSetters`.
@param {Object.<string, ?>} values an object with values for the
       uniforms.
  You can pass multiple objects by putting them in an array or by calling with more arguments.For example

    var sharedUniforms = {
      u_fogNear: 10,
      u_projection: ...
      ...
    };

    var localUniforms = {
      u_world: ...
      u_diffuseColor: ...
    };

    twgl.setUniforms(programInfo, sharedUniforms, localUniforms);

    // is the same as

    twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]);

    // is the same as

    twgl.setUniforms(programInfo, sharedUniforms);
    twgl.setUniforms(programInfo, localUniforms};

@memberOf module:twgl/programs