All files / core/src/utilities textureSupport.ts

89.09% Statements 49/55
63.15% Branches 12/19
100% Functions 6/6
89.09% Lines 49/55

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161428x 428x 428x 428x     856x 856x 856x 856x 856x 856x       856x           856x                               856x 856x 856x         856x 856x 856x 856x       856x 856x 856x 856x       856x 856x 856x 856x   856x       856x 856x 856x                       856x 856x 856x 856x 856x   856x 856x                 856x   856x 856x 856x     856x             428x             428x         428x 428x           428x 428x                                                          
const canvasSize = 4;
const texWidth = 5;
const texHeight = 1;
const pixelToCheck = [1, 1];
 
function main({ ext, filterType, texData, internalFormat, glDataType }) {
  try {
    const canvas = document.createElement('canvas');
    canvas.width = canvasSize;
    canvas.height = canvasSize;
    const gl = canvas.getContext('webgl2');
    Iif (!gl) {
      return false;
    }
 
    const vs = `#version 300 es
    void main() {
      gl_PointSize = ${canvasSize.toFixed(1)};
      gl_Position = vec4(0, 0, 0, 1);
    }
  `;
    const fs = `#version 300 es
    precision highp float;
    precision highp int;
    precision highp sampler2D;
 
    uniform sampler2D u_image;
 
    out vec4 color;
 
    void main() {
        vec4 intColor = texture(u_image, gl_PointCoord.xy);
        color = vec4(vec3(intColor.rrr), 1);
    }
    `;
 
    let extToUse;
    Eif (ext) {
      extToUse = gl.getExtension(ext);
      Iif (!extToUse) {
        return false;
      }
    }
 
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vs);
    gl.compileShader(vertexShader);
    Iif (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
      return false;
    }
 
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fs);
    gl.compileShader(fragmentShader);
    Iif (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
      return false;
    }
 
    const program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
 
    Iif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
      return false;
    }
 
    const tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texImage2D(
      gl.TEXTURE_2D,
      0,
      internalFormat(gl, extToUse),
      texWidth,
      texHeight,
      0,
      gl.RED,
      glDataType(gl, extToUse),
      texData
    );
 
    const filter = filterType === 'LINEAR' ? gl.LINEAR : gl.NEAREST;
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);
    gl.useProgram(program);
    gl.drawArrays(gl.POINTS, 0, 1);
 
    const pixel = new Uint8Array(4);
    gl.readPixels(
      pixelToCheck[0],
      pixelToCheck[1],
      1,
      1,
      gl.RGBA,
      gl.UNSIGNED_BYTE,
      pixel
    );
    const [r, g, b] = pixel;
 
    const webglLoseContext = gl.getExtension('WEBGL_lose_context');
    Eif (webglLoseContext) {
      webglLoseContext.loseContext();
    }
 
    return r === g && g === b && r !== 0;
  } catch (e) {
    return false;
  }
}
 
export function getSupportedTextureFormats() {
  const norm16TexData = new Int16Array([
    32767, 2000, 3000, 4000, 5000, 16784, 7000, 8000, 9000, 32767,
  ]);
 
  // const floatTexData = new Float32Array([0.3, 0.2, 0.3, 0.4, 0.5]);
  // const halfFloatTexData = new Uint16Array([13517, 12902, 13517, 13926, 14336]);
 
  return {
    norm16: main({
      ext: 'EXT_texture_norm16',
      filterType: 'NEAREST',
      texData: norm16TexData,
      internalFormat: (gl, ext) => ext.R16_SNORM_EXT,
      glDataType: (gl) => gl.SHORT,
    }),
    norm16Linear: main({
      ext: 'EXT_texture_norm16',
      filterType: 'LINEAR',
      texData: norm16TexData,
      internalFormat: (gl, ext) => ext.R16_SNORM_EXT,
      glDataType: (gl) => gl.SHORT,
    }),
    // float: main({
    //   filterType: 'NEAREST',
    //   texData: floatTexData,
    //   internalFormat: (gl) => gl.R16F,
    //   glDataType: (gl) => gl.FLOAT,
    // }),
    // floatLinear: main({
    //   ext: 'OES_texture_float_linear',
    //   filterType: 'LINEAR',
    //   texData: floatTexData,
    //   internalFormat: (gl) => gl.R16F,
    //   glDataType: (gl) => gl.FLOAT,
    // }),
    // halfFloat: main({
    //   filterType: 'NEAREST',
    //   texData: halfFloatTexData,
    //   internalFormat: (gl) => gl.R16F,
    //   glDataType: (gl) => gl.HALF_FLOAT,
    // }),
    // halfFloatLinear: main({
    //   filterType: 'LINEAR',
    //   texData: halfFloatTexData,
    //   internalFormat: (gl) => gl.R16F,
    //   glDataType: (gl) => gl.HALF_FLOAT,
    // }),
  };
}