Guest User

Untitled

a guest
Oct 12th, 2020
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 15.63 KB | None | 0 0
  1. <html>
  2. <body>
  3. <img src="webgl.png">
  4. <img src="webglati.png">
  5. <canvas id="example" width="1024" height="1024" style="width: 40px; height: 40px;">
  6. </canvas>
  7. <script>
  8.  
  9. window.onload = main;
  10.  
  11. WebGLTestUtils = (function() {
  12.  
  13. var simpleTextureVertexShader = '' +
  14.   'attribute vec4 vPosition;\n' +
  15.   'attribute vec2 texCoord0;\n' +
  16.   'varying vec2 texCoord;\n' +
  17.   'void main() {\n' +
  18.   '    gl_Position = vPosition;\n' +
  19.   '    texCoord = texCoord0;\n' +
  20.   '}\n';
  21.  
  22. var simpleTextureFragmentShader = '' +
  23.   'precision mediump float;\n' +
  24.   'uniform sampler2D tex;\n' +
  25.   'varying vec2 texCoord;\n' +
  26.   'void main() {\n' +
  27.   '    gl_FragData[0] = texture2D(tex, texCoord);\n' +
  28.   '}\n';
  29.  
  30. var setupSimpleTextureVertexShader = function(gl) {
  31.     return loadShader(gl, simpleTextureVertexShader, gl.VERTEX_SHADER);
  32. };
  33.  
  34. var setupSimpleTextureFragmentShader = function(gl) {
  35.     return loadShader(
  36.         gl, simpleTextureFragmentShader, gl.FRAGMENT_SHADER);
  37. };
  38.  
  39. var setupProgram = function(gl, shaders, opt_attribs, opt_locations) {
  40.   var program = gl.createProgram();
  41.   for (var ii = 0; ii < shaders.length; ++ii) {
  42.    gl.attachShader(program, shaders[ii]);
  43.  }
  44.  if (opt_attribs) {
  45.    for (var ii = 0; ii < opt_attribs.length; ++ii) {
  46.      gl.bindAttribLocation(
  47.          program,
  48.          opt_locations ? opt_locations[ii] : ii,
  49.          opt_attribs[ii]);
  50.    }
  51.  }
  52.  gl.linkProgram(program);
  53.  
  54.  var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
  55.  if (!linked) {
  56.      lastError = gl.getProgramInfoLog (program);
  57.  
  58.      gl.deleteProgram(program);
  59.      return null;
  60.  }
  61.  
  62.  gl.useProgram(program);
  63.  return program;
  64. };
  65.  
  66. var setupSimpleTextureProgram = function(
  67.    gl, opt_positionLocation, opt_texcoordLocation) {
  68.  opt_positionLocation = opt_positionLocation || 0;
  69.  opt_texcoordLocation = opt_texcoordLocation || 1;
  70.  var vs = setupSimpleTextureVertexShader(gl);
  71.  var fs = setupSimpleTextureFragmentShader(gl);
  72.  if (!vs || !fs) {
  73.    return null;
  74.  }
  75.  var program = setupProgram(
  76.      gl,
  77.      [vs, fs],
  78.      ['vPosition', 'texCoord0'],
  79.      [opt_positionLocation, opt_texcoordLocation]);
  80.  if (!program) {
  81.    gl.deleteShader(fs);
  82.    gl.deleteShader(vs);
  83.  }
  84.  gl.useProgram(program);
  85.  return program;
  86. };
  87.  
  88. var setupUnitQuad = function(gl, opt_positionLocation, opt_texcoordLocation) {
  89.  opt_positionLocation = opt_positionLocation || 0;
  90.  opt_texcoordLocation = opt_texcoordLocation || 1;
  91.  var objects = [];
  92.  
  93.  var vertexObject = gl.createBuffer();
  94.  gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
  95.  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
  96.       1.0,  1.0, 0.0,
  97.      -1.0,  1.0, 0.0,
  98.      -1.0, -1.0, 0.0,
  99.       1.0,  1.0, 0.0,
  100.      -1.0, -1.0, 0.0,
  101.       1.0, -1.0, 0.0]), gl.STATIC_DRAW);
  102.  gl.enableVertexAttribArray(opt_positionLocation);
  103.  gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
  104.  objects.push(vertexObject);
  105.  
  106.  var vertexObject = gl.createBuffer();
  107.  gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
  108.  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
  109.      1.0, 1.0,
  110.      0.0, 1.0,
  111.      0.0, 0.0,
  112.      1.0, 1.0,
  113.      0.0, 0.0,
  114.      1.0, 0.0]), gl.STATIC_DRAW);
  115.  gl.enableVertexAttribArray(opt_texcoordLocation);
  116.  gl.vertexAttribPointer(opt_texcoordLocation, 2, gl.FLOAT, false, 0, 0);
  117.  objects.push(vertexObject);
  118.  return objects;
  119. };
  120.  
  121. var setupTexturedQuad = function(
  122.    gl, opt_positionLocation, opt_texcoordLocation) {
  123.  var program = setupSimpleTextureProgram(
  124.      gl, opt_positionLocation, opt_texcoordLocation);
  125.  setupUnitQuad(gl, opt_positionLocation, opt_texcoordLocation);
  126.  return program;
  127. };
  128.  
  129. var fillTexture = function(gl, tex, width, height, color, opt_level) {
  130.  opt_level = opt_level || 0;
  131.  var numPixels = width * height;
  132.  var size = numPixels * 4;
  133.  var buf = new Uint8Array(size);
  134.  for (var ii = 0; ii < numPixels; ++ii) {
  135.    var off = ii * 4;
  136.    buf[off + 0] = color[0];
  137.    buf[off + 1] = color[1];
  138.    buf[off + 2] = color[2];
  139.    buf[off + 3] = color[3];
  140.  }
  141.  gl.bindTexture(gl.TEXTURE_2D, tex);
  142.  gl.texImage2D(
  143.      gl.TEXTURE_2D, opt_level, gl.RGBA, width, height, 0,
  144.      gl.RGBA, gl.UNSIGNED_BYTE, buf);
  145.  };
  146.  
  147. var createColoredTexture = function(gl, width, height, color) {
  148.  var tex = gl.createTexture();
  149.  fillTexture(gl, tex, width, height, color);
  150.  return tex;
  151. };
  152.  
  153. var drawQuad = function(gl, opt_color) {
  154.  opt_color = opt_color || [255, 255, 255, 255];
  155.  gl.clearColor(
  156.      opt_color[0] / 255,
  157.      opt_color[1] / 255,
  158.      opt_color[2] / 255,
  159.      opt_color[3] / 255);
  160.  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  161.  gl.drawArrays(gl.TRIANGLES, 0, 6);
  162. };
  163.  
  164. var checkCanvasRect = function(gl, x, y, width, height, color, msg, errorRange) {
  165.  errorRange = errorRange || 0;
  166.  var buf = new Uint8Array(width * height * 4);
  167.  gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
  168.  for (var i = 0; i < width * height; ++i) {
  169.    var offset = i * 4;
  170.    for (var j = 0; j < color.length; ++j) {
  171.      if (Math.abs(buf[offset + j] - color[j]) > errorRange) {
  172.         var was = buf[offset + 0].toString();
  173.         for (j = 1; j < color.length; ++j) {
  174.          was += "," + buf[offset + j];
  175.        }
  176.        return;
  177.      }
  178.    }
  179.  }
  180. };
  181.  
  182. var checkCanvas = function(gl, color, msg, errorRange) {
  183.  checkCanvasRect(gl, 0, 0, gl.canvas.width, gl.canvas.height, color, msg, errorRange);
  184. };
  185.  
  186. var loadTexture = function(gl, url, callback) {
  187.    var texture = gl.createTexture();
  188.    gl.bindTexture(gl.TEXTURE_2D, texture);
  189.    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  190.    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  191.    var image = new Image();
  192.    image.onload = function() {
  193.        gl.bindTexture(gl.TEXTURE_2D, texture);
  194.        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
  195.        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
  196.        callback(image);
  197.    };
  198.    image.src = url;
  199.    return texture;
  200. };
  201.  
  202. var create3DContext = function(opt_canvas, opt_attributes) {
  203.  opt_canvas = opt_canvas || document.createElement("canvas");
  204.  var context = null;
  205.  try {
  206.    context = opt_canvas.getContext("webgl", opt_attributes);
  207.  } catch(e) {}
  208.  if (!context) {
  209.    try {
  210.      context = opt_canvas.getContext("experimental-webgl", opt_attributes);
  211.    } catch(e) {}
  212.  }
  213.  return context;
  214. }
  215.  
  216. var getGLErrorAsString = function(gl, err) {
  217.  if (err === gl.NO_ERROR) {
  218.    return "NO_ERROR";
  219.  }
  220.  for (var name in gl) {
  221.    if (gl[name] === err) {
  222.      return name;
  223.    }
  224.  }
  225.  return err.toString();
  226. };
  227.  
  228. var createGLErrorWrapper = function(context, fname) {
  229.  return function() {
  230.    var rv = context[fname].apply(context, arguments);
  231.    var err = context.getError();
  232.    if (err != 0)
  233.      throw "GL error " + getGLErrorAsString(err) + " in " + fname;
  234.    return rv;
  235.  };
  236. };
  237.  
  238. function create3DContextWithWrapperThatThrowsOnGLError(canvas) {
  239.  var context = create3DContext(canvas);
  240.  var wrap = {};
  241.  for (var i in context) {
  242.    try {
  243.      if (typeof context[i] == 'function') {
  244.        wrap[i] = createGLErrorWrapper(context, i);
  245.      } else {
  246.        wrap[i] = context[i];
  247.      }
  248.    } catch (e) {
  249.    }
  250.  }
  251.  wrap.getError = function() {
  252.      return context.getError();
  253.  };
  254.  return wrap;
  255. };
  256.  
  257. var shouldGenerateGLError = function(gl, glError, evalStr) {
  258.  var exception;
  259.  try {
  260.    eval(evalStr);
  261.  } catch (e) {
  262.    exception = e;
  263.  }
  264. };
  265.  
  266. var glErrorShouldBe = function(gl, glError, opt_msg) {
  267.  opt_msg = opt_msg || "";
  268.  var err = gl.getError();
  269. };
  270.  
  271. var linkProgram = function(gl, program) {
  272.  gl.linkProgram(program);
  273.  
  274.  var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
  275.  if (!linked) {
  276.    var error = gl.getProgramInfoLog (program);
  277.  
  278.    gl.deleteProgram(program);
  279.    gl.deleteProgram(fragmentShader);
  280.    gl.deleteProgram(vertexShader);
  281.  }
  282. };
  283.  
  284. var setupWebGLWithShaders = function(
  285.   canvasName, vshader, fshader, attribs) {
  286.  var canvas = document.getElementById(canvasName);
  287.  var gl = create3DContext(canvas);
  288.  
  289.  var vertexShader = loadShaderFromScript(gl, vshader);
  290.  var fragmentShader = loadShaderFromScript(gl, fshader);
  291.  
  292.  if (!vertexShader || !fragmentShader) {
  293.    return null;
  294.  }
  295.  
  296.  program = gl.createProgram();
  297.  
  298.  if (!program) {
  299.    return null;
  300.  }
  301.  
  302.  gl.attachShader (program, vertexShader);
  303.  gl.attachShader (program, fragmentShader);
  304.  
  305.  for (var i in attribs) {
  306.    gl.bindAttribLocation (program, i, attribs[i]);
  307.  }
  308.  
  309.  linkProgram(gl, program);
  310.  
  311.  gl.useProgram(program);
  312.  
  313.  gl.clearColor(0,0,0,1);
  314.  gl.clearDepth(1);
  315.  
  316.  gl.enable(gl.DEPTH_TEST);
  317.  gl.enable(gl.BLEND);
  318.  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
  319.  
  320.  gl.program = program;
  321.  return gl;
  322. };
  323.  
  324. var readFile = function(file) {
  325.  var xhr = new XMLHttpRequest();
  326.  xhr.open("GET", file, false);
  327.  xhr.send();
  328.  return xhr.responseText.replace(/\r/g, "");
  329. };
  330.  
  331. var loadShader = function(gl, shaderSource, shaderType) {
  332.  var shader = gl.createShader(shaderType);
  333.  if (shader == null) {
  334.    return null;
  335.  }
  336.  
  337.  gl.shaderSource(shader, shaderSource);
  338.  var err = gl.getError();
  339.  if (err != gl.NO_ERROR) {
  340.    return null;
  341.  }
  342.  
  343.  gl.compileShader(shader);
  344.  
  345.  var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  346.  if (!compiled) {
  347.    lastError = gl.getShaderInfoLog(shader);
  348.    gl.deleteShader(shader);
  349.    return null;
  350.  }
  351.  
  352.  return shader;
  353. }
  354.  
  355. var loadShaderFromFile = function(gl, file, type) {
  356.  var shaderSource = readFile(file);
  357.  return loadShader(gl, shaderSource, type);
  358. };
  359.  
  360. var loadShaderFromScript = function(gl, scriptId, opt_shaderType) {
  361.  var shaderSource = "";
  362.  var shaderType;
  363.  var shaderScript = document.getElementById(scriptId);
  364.  if (!shaderScript) {
  365.    throw("*** Error: unknown script element" + scriptId);
  366.  }
  367.  shaderSource = shaderScript.text;
  368.  
  369.  if (!opt_shaderType) {
  370.    if (shaderScript.type == "x-shader/x-vertex") {
  371.      shaderType = gl.VERTEX_SHADER;
  372.    } else if (shaderScript.type == "x-shader/x-fragment") {
  373.      shaderType = gl.FRAGMENT_SHADER;
  374.    } else if (shaderType != gl.VERTEX_SHADER && shaderType != gl.FRAGMENT_SHADER) {
  375.      throw("*** Error: unknown shader type");
  376.      return null;
  377.    }
  378.  }
  379.  
  380.  return loadShader(
  381.      gl, shaderSource, opt_shaderType ? opt_shaderType : shaderType);
  382. };
  383.  
  384. var loadStandardProgram = function(gl) {
  385.  var program = gl.createProgram();
  386.  gl.attachShader(program, loadStandardVertexShader(gl));
  387.  gl.attachShader(program, loadStandardFragmentShader(gl));
  388.  linkProgram(gl, program);
  389.  return program;
  390. };
  391.  
  392. var loadProgramFromFile = function(gl, vertexShaderPath, fragmentShaderPath) {
  393.  var program = gl.createProgram();
  394.  gl.attachShader(
  395.      program,
  396.      loadShaderFromFile(gl, vertexShaderPath, gl.VERTEX_SHADER));
  397.  gl.attachShader(
  398.      program,
  399.      loadShaderFromFile(gl, fragmentShaderPath, gl.FRAGMENT_SHADER));
  400.  linkProgram(gl, program);
  401.  return program;
  402. };
  403.  
  404. var loadProgramFromScript = function loadProgramFromScript(
  405.  gl, vertexScriptId, fragmentScriptId) {
  406.  var program = gl.createProgram();
  407.  gl.attachShader(
  408.      program,
  409.      loadShaderFromScript(gl, vertexScriptId, gl.VERTEX_SHADER));
  410.  gl.attachShader(
  411.      program,
  412.      loadShaderFromScript(gl, fragmentScriptId,  gl.FRAGMENT_SHADER));
  413.  linkProgram(gl, program);
  414.  return program;
  415. };
  416.  
  417. var loadProgram = function(gl, vertexShader, fragmentShader) {
  418.  var program = gl.createProgram();
  419.  gl.attachShader(
  420.      program,
  421.      loadShader(gl, vertexShader, gl.VERTEX_SHADER));
  422.  gl.attachShader(
  423.      program,
  424.      loadShader(gl, fragmentShader,  gl.FRAGMENT_SHADER));
  425.  linkProgram(gl, program);
  426.  return program;
  427. };
  428.  
  429. var loadStandardVertexShader = function(gl) {
  430.  return loadShaderFromFile(
  431.      gl, "resources/vertexShader.vert", gl.VERTEX_SHADER);
  432. };
  433.  
  434. var loadStandardFragmentShader = function(gl) {
  435.  return loadShaderFromFile(
  436.      gl, "resources/fragmentShader.frag", gl.FRAGMENT_SHADER);
  437. };
  438.  
  439. var loadImageAsync = function(url, callback) {
  440.  var img = document.createElement('img');
  441.  img.onload = function() {
  442.    callback(img);
  443.  };
  444.  img.src = url;
  445. };
  446.  
  447. var loadImagesAsync = function(urls, callback) {
  448.  var count = 1;
  449.  var images = { };
  450.  function countDown() {
  451.    --count;
  452.    if (count == 0) {
  453.      callback(images);
  454.    }
  455.  }
  456.  function imageLoaded(url) {
  457.    return function(img) {
  458.      images[url] = img;
  459.      countDown();
  460.    }
  461.  }
  462.  for (var ii = 0; ii < urls.length; ++ii) {
  463.    ++count;
  464.    loadImageAsync(urls[ii], imageLoaded(urls[ii]));
  465.  }
  466.  countDown();
  467. };
  468.  
  469. return {
  470.  create3DContext: create3DContext,
  471.  create3DContextWithWrapperThatThrowsOnGLError:
  472.    create3DContextWithWrapperThatThrowsOnGLError,
  473.  checkCanvas: checkCanvas,
  474.  checkCanvasRect: checkCanvasRect,
  475.  createColoredTexture: createColoredTexture,
  476.  drawQuad: drawQuad,
  477.  glErrorShouldBe: glErrorShouldBe,
  478.  fillTexture: fillTexture,
  479.  loadImageAsync: loadImageAsync,
  480.  loadImagesAsync: loadImagesAsync,
  481.  loadProgram: loadProgram,
  482.  loadProgramFromFile: loadProgramFromFile,
  483.  loadProgramFromScript: loadProgramFromScript,
  484.  loadShader: loadShader,
  485.  loadShaderFromFile: loadShaderFromFile,
  486.  loadShaderFromScript: loadShaderFromScript,
  487.  loadStandardProgram: loadStandardProgram,
  488.  loadStandardVertexShader: loadStandardVertexShader,
  489.  loadStandardFragmentShader: loadStandardFragmentShader,
  490.  loadTexture: loadTexture,
  491.  setupProgram: setupProgram,
  492.  setupSimpleTextureFragmentShader: setupSimpleTextureFragmentShader,
  493.  setupSimpleTextureProgram: setupSimpleTextureProgram,
  494.  setupSimpleTextureVertexShader: setupSimpleTextureVertexShader,
  495.  setupTexturedQuad: setupTexturedQuad,
  496.  setupUnitQuad: setupUnitQuad,
  497.  setupWebGLWithShaders: setupWebGLWithShaders,
  498.  shouldGenerateGLError: shouldGenerateGLError,
  499.  readFile: readFile,
  500.  
  501.  none: false
  502. };
  503.  
  504. }());
  505.  
  506. function main() {
  507.  var wtu = WebGLTestUtils;
  508.  var canvas = document.getElementById("example");
  509.  var gl = wtu.create3DContext(canvas);
  510.  var program = wtu.setupTexturedQuad(gl);
  511.  
  512.  var tex = gl.createTexture();
  513.  gl.enable(gl.BLEND);
  514.  gl.disable(gl.DEPTH_TEST);
  515.  
  516.  wtu.fillTexture(gl, tex, 4096, 4096, [0, 192, 128, 255], 0);
  517.  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating texture");
  518.  
  519.  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  520.  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  521.  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  522.  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  523.  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting texture params");
  524.  
  525.  var loc = gl.getUniformLocation(program, "tex");
  526.  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after getting tex locations");
  527.  gl.uniform1i(loc, 0);
  528.  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting tex uniform");
  529.  
  530.  var numQuads = 100000;
  531.  var indexBuf = new ArrayBuffer(numQuads * 6);
  532.  var indices = new Uint8Array(indexBuf);
  533.  for (var ii = 0; ii < numQuads; ++ii) {
  534.    var offset = ii * 6;
  535.    indices[offset + 0] = 0;
  536.    indices[offset + 1] = 1;
  537.    indices[offset + 2] = 2;
  538.    indices[offset + 3] = 3;
  539.    indices[offset + 4] = 4;
  540.    indices[offset + 5] = 5;
  541.  }
  542.  var indexBuffer = gl.createBuffer();
  543.  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
  544.  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
  545.  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating index buffer");
  546.  gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_BYTE, 0);
  547.  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
  548.  
  549.  successfullyParsed = true;
  550. }
  551. </script>
  552. </body>
  553. </html>
Add Comment
Please, Sign In to add comment