tor-browser

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

texture-mips.html (8828B)


      1 <!--
      2 Copyright (c) 2019 The Khronos Group Inc.
      3 Use of this source code is governed by an MIT-style license that can be
      4 found in the LICENSE.txt file.
      5 -->
      6 
      7 <!DOCTYPE html>
      8 <html>
      9 <head>
     10 <meta charset="utf-8">
     11 <title>WebGL texture mips conformance test.</title>
     12 <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
     13 <script src="../../../js/js-test-pre.js"></script>
     14 <script src="../../../js/webgl-test-utils.js"></script>
     15 </head>
     16 <body>
     17 <canvas id="example" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
     18 <div id="description"></div>
     19 <div id="console"></div>
     20 <script id="vshader" type="x-shader/x-vertex">
     21 uniform vec4 uMult;
     22 attribute vec4 vPosition;
     23 attribute vec2 texCoord0;
     24 varying vec2 texCoord;
     25 void main()
     26 {
     27    gl_Position = vPosition * uMult;
     28    texCoord = texCoord0;
     29 }
     30 </script>
     31 
     32 <script id="fshader" type="x-shader/x-fragment">
     33 precision mediump float;
     34 uniform sampler2D tex;
     35 varying vec2 texCoord;
     36 void main()
     37 {
     38    gl_FragColor = texture2D(tex, texCoord);
     39 }
     40 </script>
     41 <script>
     42 "use strict";
     43 var canvas;
     44 var wtu = WebGLTestUtils;
     45 function init()
     46 {
     47  description("Checks mip issues");
     48 
     49  canvas = document.getElementById("example");
     50  shouldBe("canvas.width", "2");
     51  shouldBe("canvas.height", "2");
     52 
     53  var gl = wtu.create3DContext(canvas);
     54 
     55  var tex = gl.createTexture();
     56  gl.bindTexture(gl.TEXTURE_2D, tex);
     57  gl.generateMipmap(gl.TEXTURE_2D);
     58  wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "for generateMipmap with mip 0 is 0x0");
     59  gl.texImage2D(
     60      gl.TEXTURE_2D, 1, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
     61      new Uint8Array(4));
     62  gl.generateMipmap(gl.TEXTURE_2D);
     63  wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "for generateMipmap with mip 0 is 0x0");
     64 
     65  tex = gl.createTexture();
     66  gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
     67  gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
     68  wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "for generateMipmap with mip 0 is 0x0");
     69 
     70  var faces = [
     71    gl.TEXTURE_CUBE_MAP_POSITIVE_X,
     72    gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
     73    gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
     74    gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
     75    gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
     76    gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
     77  ];
     78  for (var ii = 0; ii < faces.length; ++ii) {
     79    gl.texImage2D(
     80        faces[ii], 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE,
     81        new Uint8Array(4 * 2 * 2));
     82    gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
     83    wtu.glErrorShouldBe(gl, ii == 5 ? gl.NO_ERROR : gl.INVALID_OPERATION, "for generateMipmap with " + (ii + 1) + " faces");
     84  }
     85 
     86  wtu.setupUnitQuad(gl, 0, 1);
     87  var program = wtu.setupProgram(
     88      gl, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
     89 
     90  gl.disable(gl.DEPTH_TEST);
     91  gl.disable(gl.BLEND);
     92 
     93  var colors = {
     94    blue: [0, 0, 255, 255],
     95    red: [255, 0, 0, 255],
     96    green:  [0, 255, 0, 255],
     97    cyan: [128, 255, 255, 255],
     98    black: [0, 0, 0, 255],
     99    blank: [0, 0, 0, 0]
    100  };
    101 
    102  var mips = [
    103  ];
    104 
    105  var texLoc = gl.getUniformLocation(program, "tex");
    106  gl.uniform1i(texLoc, 0);
    107  var multLoc = gl.getUniformLocation(program, "uMult");
    108 
    109  // ----------------------------------------------------
    110  var clearTex = createTexture();
    111  gl.uniform4f(multLoc, 1, 1, 1, 1);
    112  gl.bindTexture(gl.TEXTURE_2D, clearTex);
    113  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    114  debug('gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);');
    115  setMipData(0, 16, 'blank');
    116  makeDivMipChain();
    117  generateMipmap();
    118  check('blank', "texture created with null that has all mips");
    119 
    120  // ----------------------------------------------------
    121  var tex = createTexture();
    122  gl.uniform4f(multLoc, 1, 1, 1, 1);
    123 
    124  gl.bindTexture(gl.TEXTURE_2D, tex);
    125  // 16x16 texture no mips
    126  fillLevel(tex, 0, 16, 'cyan');
    127 
    128  check('black',
    129        "texture that is missing mips when TEXTURE_MIN_FILTER not NEAREST or LINEAR");
    130 
    131  generateMipmap();
    132 
    133  check('cyan', "texture that has all mips");
    134 
    135  // Fill in the bottom 2 mips with a different color.
    136  fillLevel(tex, 4, 1, 'green');
    137  fillLevel(tex, 3, 2, 'green');
    138 
    139  // Choose the nearest mip
    140  texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
    141 
    142  check('green', "texture that is only using the smallest 2 mips");
    143 
    144  gl.uniform4f(multLoc, 16, 16, 1, 1);
    145 
    146  check('cyan', "texture that is using only the largest 2 mips");
    147 
    148  // Set the top level
    149  fillLevel(tex, 0, 1, 'red');
    150  check('red',
    151        "texture that is only using the top level even though other levels are defined");
    152 
    153  // Set the top 2 levels using generateMipmap
    154  fillLevel(tex, 0, 2, 'blue');
    155  generateMipmap();
    156 
    157  check('blue',
    158        "texture that is only using the top 2 levels even though other levels are defined");
    159 
    160  // Set the top 2 levels back to sizes that end up using levels 2, 3, and 4 again.
    161  fillLevel(tex, 0, 16, 'blue');
    162  fillLevel(tex, 1, 8, 'blue');
    163  check('blue', "texture that is only using the largest 2 mips");
    164  gl.uniform4f(multLoc, 1, 1, 1, 1);
    165  check('green', "texture that is only using the smallest 2 mips");
    166 
    167  // ----------------------------------------------------
    168  var tex = createTexture();
    169  gl.uniform4f(multLoc, 1, 1, 1, 1);
    170  fillLevel(tex, 0, 8, 'cyan');
    171  generateMipmap();
    172  check('cyan', "texture that has 3 mips");
    173 
    174  fillLevel(tex, 0, 16, 'blue');
    175  texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    176  check('blue', "texture that is only using top mips");
    177 
    178  fillLevel(tex, 0, 8, 'red');
    179  texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
    180  check('cyan', "texture that is only using smallest mips");
    181 
    182  gl.uniform4f(multLoc, 16, 16, 1, 1);
    183  check('red', "texture that is using only the largest mip");
    184 
    185  // ----------------------------------------------------
    186  var tex = createTexture();
    187  gl.uniform4f(multLoc, 1, 1, 1, 1);
    188  fillLevel(tex, 2, 1, 'green');
    189  fillLevel(tex, 1, 2, 'green');
    190  fillLevel(tex, 0, 4, 'green');
    191  check('green', "texture that was built smallest mip first");
    192 
    193  // ----------------------------------------------------
    194  var tex = createTexture();
    195  gl.uniform4f(multLoc, 1, 1, 1, 1);
    196  fillLevel(tex, 0, 16, 'red');
    197  generateMipmap();
    198  check('red', "texture with 1 genmipmaps");
    199  fillLevel(tex, 0, 16, 'blue');
    200  generateMipmap();
    201  fillLevel(tex, 0, 16, 'green');
    202  generateMipmap();
    203  check('green', "texture with 2 genmipmaps");
    204 
    205  // ----------------------------------------------------
    206  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
    207 
    208  function createTexture() {
    209    debug("<hr/>gl.createTexture()");
    210    mips = [];
    211    makeDivMipChain();
    212    return gl.createTexture();
    213  }
    214 
    215  function texParameteri(target, pname, value) {
    216    debug("gl.texParameteri(" +
    217          wtu.glEnumToString(gl, target) + ", " +
    218          wtu.glEnumToString(gl, pname) + ", " +
    219          wtu.glEnumToString(gl, value) + ")")
    220    gl.texParameteri(target, pname, value);
    221  }
    222 
    223  function generateMipmap() {
    224    debug("gl.generateMipmap(gl.TEXTURE_2D)");
    225    gl.generateMipmap(gl.TEXTURE_2D);
    226    var mip0 = mips[0];
    227    var size = mip0.size;
    228    var level = 1;
    229    for(;;) {
    230      size = Math.floor(size / 2);
    231      if (!size) {
    232        break;
    233      }
    234      setMipData(level, size, mip0.color);
    235      ++level;
    236    }
    237    makeDivMipChain();
    238  }
    239 
    240  function check(color, msg) {
    241    wtu.clearAndDrawUnitQuad(gl);
    242    wtu.checkCanvas(gl, colors[color], msg + " should draw with " + color);
    243  }
    244 
    245  function fillLevel(tex, level, size, color) {
    246    setMipData(level, size, color);
    247    debug("gl.texImage2D(gl.TEXTURE_2D, " + level + ", gl.RGBA, " + size + ", " + size +
    248          ", 0, gl.RGBA, gl.UNSIGNED_BYTE, " + color + ");");
    249    wtu.fillTexture(gl, tex, size, size, colors[color], level);
    250    makeDivMipChain();
    251  }
    252 
    253  function setMipData(level, size, color) {
    254    mips[level] = {
    255      size: size,
    256      color: color
    257    };
    258  }
    259 
    260  function makeDivMipChain(color) {
    261    var html = [
    262      '<div style="height: 68px; margin-top: 5px">',
    263      '<div style="float:left;">mips: </div>'];
    264    for (var ii = 0; ii < 5; ++ii) {
    265      var mip = mips[ii];
    266      if (mip) {
    267        html.push(makeDivSquare(mip.size, mip.color));
    268      } else {
    269        html.push(makeDivSquare(16, undefined));
    270      }
    271    }
    272    html.push("</div>");
    273    debug(html.join(""));
    274  }
    275 
    276  function makeDivSquare(size, color) {
    277    size *= 4;
    278    var c = color ? colors[color] : [255,255,255];
    279    var border = color ? 'solid' : 'dashed';
    280    return '<div style="float:left; width: ' + size + 'px; height: ' + size +
    281           'px; background-color: ' + rgb(c) +
    282           '; border: 1px ' + border + ' black; margin-right: 3px;"></div>';
    283  }
    284 
    285  function rgb(c) {
    286    return 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] +')';
    287  }
    288 }
    289 
    290 init();
    291 var successfullyParsed = true;
    292 </script>
    293 <script src="../../../js/js-test-post.js"></script>
    294 
    295 </body>
    296 </html>