tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

webgl-test-utils.js (10329B)


      1 // Copyright 2011 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 WebGLTestUtils = (function() {
      6  /**
      7   * Converts a WebGL enum to a string
      8   * @param {!WebGLContext} gl The WebGLContext to use.
      9   * @param {number} value The enum value.
     10   * @return {string} The enum as a string.
     11   */
     12  var glEnumToString = function(gl, value) {
     13    for (var p in gl) {
     14      if (gl[p] == value) {
     15        return p;
     16      }
     17    }
     18    return '0x' + value.toString(16);
     19  };
     20 
     21  var lastError = '';
     22 
     23  /**
     24   * Returns the last compiler/linker error.
     25   * @return {string} The last compiler/linker error.
     26   */
     27  var getLastError = function() {
     28    return lastError;
     29  };
     30 
     31  // clang-format off
     32 
     33  /**
     34   * A vertex shader for a single texture.
     35   * @type {string}
     36   */
     37  var simpleTextureVertexShader = [
     38    'attribute vec4 vPosition;',  //
     39    'attribute vec2 texCoord0;',
     40    'varying vec2 texCoord;',
     41    'void main() {',
     42    '    gl_Position = vPosition;',
     43    '    texCoord = texCoord0;',
     44    '}'
     45  ].join('\n');
     46 
     47  /**
     48   * A fragment shader for a single texture.
     49   * @type {string}
     50   */
     51  var simpleTextureFragmentShader = [
     52    'precision mediump float;',
     53    'uniform sampler2D tex;',
     54    'varying vec2 texCoord;',
     55    'void main() {',
     56    '    gl_FragData[0] = texture2D(tex, texCoord);',
     57    '}'
     58  ].join('\n');
     59 
     60  // clang-format on
     61 
     62  /**
     63   * Creates a simple texture vertex shader.
     64   * @param {!WebGLContext} gl The WebGLContext to use.
     65   * @return {!WebGLShader}
     66   */
     67  var setupSimpleTextureVertexShader = function(gl) {
     68    return loadShader(gl, simpleTextureVertexShader, gl.VERTEX_SHADER);
     69  };
     70 
     71  /**
     72   * Creates a simple texture fragment shader.
     73   * @param {!WebGLContext} gl The WebGLContext to use.
     74   * @return {!WebGLShader}
     75   */
     76  var setupSimpleTextureFragmentShader = function(gl) {
     77    return loadShader(gl, simpleTextureFragmentShader, gl.FRAGMENT_SHADER);
     78  };
     79 
     80  /**
     81   * Creates a program, attaches shaders, binds attrib locations, links the
     82   * program and calls useProgram.
     83   * @param {!Array.<!WebGLShader>} shaders The shaders to attach .
     84   * @param {!Array.<string>} opt_attribs The attribs names.
     85   * @param {!Array.<number>} opt_locations The locations for the attribs.
     86   */
     87  var setupProgram = function(gl, shaders, opt_attribs, opt_locations) {
     88    var realShaders = [];
     89    var program = gl.createProgram();
     90    for (var ii = 0; ii < shaders.length; ++ii) {
     91      var shader = shaders[ii];
     92      if (typeof shader == 'string') {
     93        var element = document.getElementById(shader);
     94        if (element) {
     95          shader = loadShaderFromScript(gl, shader);
     96        } else {
     97          shader = loadShader(
     98              gl, shader, ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER);
     99        }
    100      }
    101      gl.attachShader(program, shader);
    102    }
    103    if (opt_attribs) {
    104      for (var ii = 0; ii < opt_attribs.length; ++ii) {
    105        gl.bindAttribLocation(
    106            program, opt_locations ? opt_locations[ii] : ii, opt_attribs[ii]);
    107      }
    108    }
    109    gl.linkProgram(program);
    110 
    111    // Check the link status
    112    var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
    113    if (!linked) {
    114      gl.deleteProgram(program);
    115      return null;
    116    }
    117 
    118    gl.useProgram(program);
    119    return program;
    120  };
    121 
    122  /**
    123   * Creates a simple texture program.
    124   * @param {!WebGLContext} gl The WebGLContext to use.
    125   * @param {number} opt_positionLocation The attrib location for position.
    126   * @param {number} opt_texcoordLocation The attrib location for texture
    127   *     coords.
    128   * @return {WebGLProgram}
    129   */
    130  var setupSimpleTextureProgram = function(
    131      gl, opt_positionLocation, opt_texcoordLocation) {
    132    opt_positionLocation = opt_positionLocation || 0;
    133    opt_texcoordLocation = opt_texcoordLocation || 1;
    134    var vs = setupSimpleTextureVertexShader(gl);
    135    var fs = setupSimpleTextureFragmentShader(gl);
    136    if (!vs || !fs) {
    137      return null;
    138    }
    139    var program = setupProgram(
    140        gl, [vs, fs], ['vPosition', 'texCoord0'],
    141        [opt_positionLocation, opt_texcoordLocation]);
    142    if (!program) {
    143      gl.deleteShader(fs);
    144      gl.deleteShader(vs);
    145    }
    146    gl.useProgram(program);
    147    return program;
    148  };
    149 
    150  /**
    151   * Creates buffers for a textured unit quad and attaches them to vertex
    152   * attribs.
    153   * @param {!WebGLContext} gl The WebGLContext to use.
    154   * @param {number} opt_positionLocation The attrib location for position.
    155   * @param {number} opt_texcoordLocation The attrib location for texture
    156   *     coords.
    157   * @return {!Array.<WebGLBuffer>} The buffer objects that were
    158   *      created.
    159   */
    160  var setupUnitQuad = function(gl, opt_positionLocation, opt_texcoordLocation) {
    161    opt_positionLocation = opt_positionLocation || 0;
    162    opt_texcoordLocation = opt_texcoordLocation || 1;
    163    var objects = [];
    164 
    165    var vertexObject = gl.createBuffer();
    166    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
    167    gl.bufferData(
    168        gl.ARRAY_BUFFER, new Float32Array([
    169          1.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0,
    170          -1.0, 0.0, 1.0, -1.0, 0.0
    171        ]),
    172        gl.STATIC_DRAW);
    173    gl.enableVertexAttribArray(opt_positionLocation);
    174    gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
    175    objects.push(vertexObject);
    176 
    177    var vertexObject = gl.createBuffer();
    178    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
    179    gl.bufferData(
    180        gl.ARRAY_BUFFER,
    181        new Float32Array(
    182            [1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0]),
    183        gl.STATIC_DRAW);
    184    gl.enableVertexAttribArray(opt_texcoordLocation);
    185    gl.vertexAttribPointer(opt_texcoordLocation, 2, gl.FLOAT, false, 0, 0);
    186    objects.push(vertexObject);
    187    return objects;
    188  };
    189 
    190  /**
    191   * Creates a program and buffers for rendering a textured quad.
    192   * @param {!WebGLContext} gl The WebGLContext to use.
    193   * @param {number} opt_positionLocation The attrib location for position.
    194   * @param {number} opt_texcoordLocation The attrib location for texture
    195   *     coords.
    196   * @return {!WebGLProgram}
    197   */
    198  var setupTexturedQuad = function(
    199      gl, opt_positionLocation, opt_texcoordLocation) {
    200    var program = setupSimpleTextureProgram(
    201        gl, opt_positionLocation, opt_texcoordLocation);
    202    setupUnitQuad(gl, opt_positionLocation, opt_texcoordLocation);
    203    return program;
    204  };
    205 
    206  /**
    207   * Draws a previously setup quad.
    208   * @param {!WebGLContext} gl The WebGLContext to use.
    209   * @param {!Array.<number>} opt_color The color to fill clear with before
    210   *        drawing. A 4 element array where each element is in the range 0 to
    211   *        255. Default [255, 255, 255, 255]
    212   */
    213  var drawQuad = function(gl, opt_color) {
    214    opt_color = opt_color || [255, 255, 255, 255];
    215    gl.clearColor(
    216        opt_color[0] / 255, opt_color[1] / 255, opt_color[2] / 255,
    217        opt_color[3] / 255);
    218    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    219    gl.drawArrays(gl.TRIANGLES, 0, 6);
    220  };
    221 
    222  /**
    223   * Links a WebGL program, throws if there are errors.
    224   * @param {!WebGLContext} gl The WebGLContext to use.
    225   * @param {!WebGLProgram} program The WebGLProgram to link.
    226   * @param {function(string): void) opt_errorCallback callback for errors.
    227   */
    228  var linkProgram = function(gl, program, opt_errorCallback) {
    229    // Link the program
    230    gl.linkProgram(program);
    231 
    232    // Check the link status
    233    var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
    234    if (!linked) {
    235      // something went wrong with the link
    236      gl.deleteProgram(program);
    237      return false;
    238    }
    239 
    240    return true;
    241  };
    242 
    243  /**
    244   * Loads a shader.
    245   * @param {!WebGLContext} gl The WebGLContext to use.
    246   * @param {string} shaderSource The shader source.
    247   * @param {number} shaderType The type of shader.
    248   * @param {function(string): void) opt_errorCallback callback for errors.
    249   * @return {!WebGLShader} The created shader.
    250   */
    251  var loadShader =
    252      function(gl, shaderSource, shaderType, opt_errorCallback) {
    253    var errFn = opt_errorCallback || (_ => {});
    254    // Create the shader object
    255    var shader = gl.createShader(shaderType);
    256    if (shader == null) {
    257      errFn('*** Error: unable to create shader \'' + shaderSource + '\'');
    258      return null;
    259    }
    260 
    261    // Load the shader source
    262    gl.shaderSource(shader, shaderSource);
    263    var err = gl.getError();
    264    if (err != gl.NO_ERROR) {
    265      errFn(
    266          '*** Error loading shader \'' + shader +
    267          '\':' + glEnumToString(gl, err));
    268      return null;
    269    }
    270 
    271    // Compile the shader
    272    gl.compileShader(shader);
    273 
    274    // Check the compile status
    275    var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    276    if (!compiled) {
    277      // Something went wrong during compilation; get the error
    278      lastError = gl.getShaderInfoLog(shader);
    279      errFn('*** Error compiling shader \'' + shader + '\':' + lastError);
    280      gl.deleteShader(shader);
    281      return null;
    282    }
    283 
    284    return shader;
    285  }
    286 
    287  /**
    288   * Loads shaders from source, creates a program, attaches the shaders and
    289   * links.
    290   * @param {!WebGLContext} gl The WebGLContext to use.
    291   * @param {string} vertexShader The vertex shader.
    292   * @param {string} fragmentShader The fragment shader.
    293   * @param {function(string): void) opt_errorCallback callback for errors.
    294   * @return {!WebGLProgram} The created program.
    295   */
    296  var loadProgram = function(
    297      gl, vertexShader, fragmentShader, opt_errorCallback) {
    298    var program = gl.createProgram();
    299    gl.attachShader(
    300        program,
    301        loadShader(gl, vertexShader, gl.VERTEX_SHADER, opt_errorCallback));
    302    gl.attachShader(
    303        program,
    304        loadShader(gl, fragmentShader, gl.FRAGMENT_SHADER, opt_errorCallback));
    305    return linkProgram(gl, program, opt_errorCallback) ? program : null;
    306  };
    307 
    308  return {
    309    drawQuad: drawQuad,
    310    getLastError: getLastError,
    311    glEnumToString: glEnumToString,
    312    loadProgram: loadProgram,
    313    loadShader: loadShader,
    314    setupProgram: setupProgram,
    315    setupSimpleTextureFragmentShader: setupSimpleTextureFragmentShader,
    316    setupSimpleTextureProgram: setupSimpleTextureProgram,
    317    setupSimpleTextureVertexShader: setupSimpleTextureVertexShader,
    318    setupTexturedQuad: setupTexturedQuad,
    319    setupUnitQuad: setupUnitQuad,
    320  };
    321 }());