Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <html>
- <body>
- <img src="webgl.png">
- <img src="webglati.png">
- <canvas id="example" width="1024" height="1024" style="width: 40px; height: 40px;">
- </canvas>
- <script>
- window.onload = main;
- WebGLTestUtils = (function() {
- var simpleTextureVertexShader = '' +
- 'attribute vec4 vPosition;\n' +
- 'attribute vec2 texCoord0;\n' +
- 'varying vec2 texCoord;\n' +
- 'void main() {\n' +
- ' gl_Position = vPosition;\n' +
- ' texCoord = texCoord0;\n' +
- '}\n';
- var simpleTextureFragmentShader = '' +
- 'precision mediump float;\n' +
- 'uniform sampler2D tex;\n' +
- 'varying vec2 texCoord;\n' +
- 'void main() {\n' +
- ' gl_FragData[0] = texture2D(tex, texCoord);\n' +
- '}\n';
- var setupSimpleTextureVertexShader = function(gl) {
- return loadShader(gl, simpleTextureVertexShader, gl.VERTEX_SHADER);
- };
- var setupSimpleTextureFragmentShader = function(gl) {
- return loadShader(
- gl, simpleTextureFragmentShader, gl.FRAGMENT_SHADER);
- };
- var setupProgram = function(gl, shaders, opt_attribs, opt_locations) {
- var program = gl.createProgram();
- for (var ii = 0; ii < shaders.length; ++ii) {
- gl.attachShader(program, shaders[ii]);
- }
- if (opt_attribs) {
- for (var ii = 0; ii < opt_attribs.length; ++ii) {
- gl.bindAttribLocation(
- program,
- opt_locations ? opt_locations[ii] : ii,
- opt_attribs[ii]);
- }
- }
- gl.linkProgram(program);
- var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
- if (!linked) {
- lastError = gl.getProgramInfoLog (program);
- gl.deleteProgram(program);
- return null;
- }
- gl.useProgram(program);
- return program;
- };
- var setupSimpleTextureProgram = function(
- gl, opt_positionLocation, opt_texcoordLocation) {
- opt_positionLocation = opt_positionLocation || 0;
- opt_texcoordLocation = opt_texcoordLocation || 1;
- var vs = setupSimpleTextureVertexShader(gl);
- var fs = setupSimpleTextureFragmentShader(gl);
- if (!vs || !fs) {
- return null;
- }
- var program = setupProgram(
- gl,
- [vs, fs],
- ['vPosition', 'texCoord0'],
- [opt_positionLocation, opt_texcoordLocation]);
- if (!program) {
- gl.deleteShader(fs);
- gl.deleteShader(vs);
- }
- gl.useProgram(program);
- return program;
- };
- var setupUnitQuad = function(gl, opt_positionLocation, opt_texcoordLocation) {
- opt_positionLocation = opt_positionLocation || 0;
- opt_texcoordLocation = opt_texcoordLocation || 1;
- var objects = [];
- var vertexObject = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
- 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, -1.0, 0.0,
- 1.0, -1.0, 0.0]), gl.STATIC_DRAW);
- gl.enableVertexAttribArray(opt_positionLocation);
- gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
- objects.push(vertexObject);
- var vertexObject = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
- 1.0, 1.0,
- 0.0, 1.0,
- 0.0, 0.0,
- 1.0, 1.0,
- 0.0, 0.0,
- 1.0, 0.0]), gl.STATIC_DRAW);
- gl.enableVertexAttribArray(opt_texcoordLocation);
- gl.vertexAttribPointer(opt_texcoordLocation, 2, gl.FLOAT, false, 0, 0);
- objects.push(vertexObject);
- return objects;
- };
- var setupTexturedQuad = function(
- gl, opt_positionLocation, opt_texcoordLocation) {
- var program = setupSimpleTextureProgram(
- gl, opt_positionLocation, opt_texcoordLocation);
- setupUnitQuad(gl, opt_positionLocation, opt_texcoordLocation);
- return program;
- };
- var fillTexture = function(gl, tex, width, height, color, opt_level) {
- opt_level = opt_level || 0;
- var numPixels = width * height;
- var size = numPixels * 4;
- var buf = new Uint8Array(size);
- for (var ii = 0; ii < numPixels; ++ii) {
- var off = ii * 4;
- buf[off + 0] = color[0];
- buf[off + 1] = color[1];
- buf[off + 2] = color[2];
- buf[off + 3] = color[3];
- }
- gl.bindTexture(gl.TEXTURE_2D, tex);
- gl.texImage2D(
- gl.TEXTURE_2D, opt_level, gl.RGBA, width, height, 0,
- gl.RGBA, gl.UNSIGNED_BYTE, buf);
- };
- var createColoredTexture = function(gl, width, height, color) {
- var tex = gl.createTexture();
- fillTexture(gl, tex, width, height, color);
- return tex;
- };
- var drawQuad = function(gl, opt_color) {
- opt_color = opt_color || [255, 255, 255, 255];
- gl.clearColor(
- opt_color[0] / 255,
- opt_color[1] / 255,
- opt_color[2] / 255,
- opt_color[3] / 255);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
- gl.drawArrays(gl.TRIANGLES, 0, 6);
- };
- var checkCanvasRect = function(gl, x, y, width, height, color, msg, errorRange) {
- errorRange = errorRange || 0;
- var buf = new Uint8Array(width * height * 4);
- gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
- for (var i = 0; i < width * height; ++i) {
- var offset = i * 4;
- for (var j = 0; j < color.length; ++j) {
- if (Math.abs(buf[offset + j] - color[j]) > errorRange) {
- var was = buf[offset + 0].toString();
- for (j = 1; j < color.length; ++j) {
- was += "," + buf[offset + j];
- }
- return;
- }
- }
- }
- };
- var checkCanvas = function(gl, color, msg, errorRange) {
- checkCanvasRect(gl, 0, 0, gl.canvas.width, gl.canvas.height, color, msg, errorRange);
- };
- var loadTexture = function(gl, url, callback) {
- var texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- var image = new Image();
- image.onload = function() {
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
- callback(image);
- };
- image.src = url;
- return texture;
- };
- var create3DContext = function(opt_canvas, opt_attributes) {
- opt_canvas = opt_canvas || document.createElement("canvas");
- var context = null;
- try {
- context = opt_canvas.getContext("webgl", opt_attributes);
- } catch(e) {}
- if (!context) {
- try {
- context = opt_canvas.getContext("experimental-webgl", opt_attributes);
- } catch(e) {}
- }
- return context;
- }
- var getGLErrorAsString = function(gl, err) {
- if (err === gl.NO_ERROR) {
- return "NO_ERROR";
- }
- for (var name in gl) {
- if (gl[name] === err) {
- return name;
- }
- }
- return err.toString();
- };
- var createGLErrorWrapper = function(context, fname) {
- return function() {
- var rv = context[fname].apply(context, arguments);
- var err = context.getError();
- if (err != 0)
- throw "GL error " + getGLErrorAsString(err) + " in " + fname;
- return rv;
- };
- };
- function create3DContextWithWrapperThatThrowsOnGLError(canvas) {
- var context = create3DContext(canvas);
- var wrap = {};
- for (var i in context) {
- try {
- if (typeof context[i] == 'function') {
- wrap[i] = createGLErrorWrapper(context, i);
- } else {
- wrap[i] = context[i];
- }
- } catch (e) {
- }
- }
- wrap.getError = function() {
- return context.getError();
- };
- return wrap;
- };
- var shouldGenerateGLError = function(gl, glError, evalStr) {
- var exception;
- try {
- eval(evalStr);
- } catch (e) {
- exception = e;
- }
- };
- var glErrorShouldBe = function(gl, glError, opt_msg) {
- opt_msg = opt_msg || "";
- var err = gl.getError();
- };
- var linkProgram = function(gl, program) {
- gl.linkProgram(program);
- var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
- if (!linked) {
- var error = gl.getProgramInfoLog (program);
- gl.deleteProgram(program);
- gl.deleteProgram(fragmentShader);
- gl.deleteProgram(vertexShader);
- }
- };
- var setupWebGLWithShaders = function(
- canvasName, vshader, fshader, attribs) {
- var canvas = document.getElementById(canvasName);
- var gl = create3DContext(canvas);
- var vertexShader = loadShaderFromScript(gl, vshader);
- var fragmentShader = loadShaderFromScript(gl, fshader);
- if (!vertexShader || !fragmentShader) {
- return null;
- }
- program = gl.createProgram();
- if (!program) {
- return null;
- }
- gl.attachShader (program, vertexShader);
- gl.attachShader (program, fragmentShader);
- for (var i in attribs) {
- gl.bindAttribLocation (program, i, attribs[i]);
- }
- linkProgram(gl, program);
- gl.useProgram(program);
- gl.clearColor(0,0,0,1);
- gl.clearDepth(1);
- gl.enable(gl.DEPTH_TEST);
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
- gl.program = program;
- return gl;
- };
- var readFile = function(file) {
- var xhr = new XMLHttpRequest();
- xhr.open("GET", file, false);
- xhr.send();
- return xhr.responseText.replace(/\r/g, "");
- };
- var loadShader = function(gl, shaderSource, shaderType) {
- var shader = gl.createShader(shaderType);
- if (shader == null) {
- return null;
- }
- gl.shaderSource(shader, shaderSource);
- var err = gl.getError();
- if (err != gl.NO_ERROR) {
- return null;
- }
- gl.compileShader(shader);
- var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
- if (!compiled) {
- lastError = gl.getShaderInfoLog(shader);
- gl.deleteShader(shader);
- return null;
- }
- return shader;
- }
- var loadShaderFromFile = function(gl, file, type) {
- var shaderSource = readFile(file);
- return loadShader(gl, shaderSource, type);
- };
- var loadShaderFromScript = function(gl, scriptId, opt_shaderType) {
- var shaderSource = "";
- var shaderType;
- var shaderScript = document.getElementById(scriptId);
- if (!shaderScript) {
- throw("*** Error: unknown script element" + scriptId);
- }
- shaderSource = shaderScript.text;
- if (!opt_shaderType) {
- if (shaderScript.type == "x-shader/x-vertex") {
- shaderType = gl.VERTEX_SHADER;
- } else if (shaderScript.type == "x-shader/x-fragment") {
- shaderType = gl.FRAGMENT_SHADER;
- } else if (shaderType != gl.VERTEX_SHADER && shaderType != gl.FRAGMENT_SHADER) {
- throw("*** Error: unknown shader type");
- return null;
- }
- }
- return loadShader(
- gl, shaderSource, opt_shaderType ? opt_shaderType : shaderType);
- };
- var loadStandardProgram = function(gl) {
- var program = gl.createProgram();
- gl.attachShader(program, loadStandardVertexShader(gl));
- gl.attachShader(program, loadStandardFragmentShader(gl));
- linkProgram(gl, program);
- return program;
- };
- var loadProgramFromFile = function(gl, vertexShaderPath, fragmentShaderPath) {
- var program = gl.createProgram();
- gl.attachShader(
- program,
- loadShaderFromFile(gl, vertexShaderPath, gl.VERTEX_SHADER));
- gl.attachShader(
- program,
- loadShaderFromFile(gl, fragmentShaderPath, gl.FRAGMENT_SHADER));
- linkProgram(gl, program);
- return program;
- };
- var loadProgramFromScript = function loadProgramFromScript(
- gl, vertexScriptId, fragmentScriptId) {
- var program = gl.createProgram();
- gl.attachShader(
- program,
- loadShaderFromScript(gl, vertexScriptId, gl.VERTEX_SHADER));
- gl.attachShader(
- program,
- loadShaderFromScript(gl, fragmentScriptId, gl.FRAGMENT_SHADER));
- linkProgram(gl, program);
- return program;
- };
- var loadProgram = function(gl, vertexShader, fragmentShader) {
- var program = gl.createProgram();
- gl.attachShader(
- program,
- loadShader(gl, vertexShader, gl.VERTEX_SHADER));
- gl.attachShader(
- program,
- loadShader(gl, fragmentShader, gl.FRAGMENT_SHADER));
- linkProgram(gl, program);
- return program;
- };
- var loadStandardVertexShader = function(gl) {
- return loadShaderFromFile(
- gl, "resources/vertexShader.vert", gl.VERTEX_SHADER);
- };
- var loadStandardFragmentShader = function(gl) {
- return loadShaderFromFile(
- gl, "resources/fragmentShader.frag", gl.FRAGMENT_SHADER);
- };
- var loadImageAsync = function(url, callback) {
- var img = document.createElement('img');
- img.onload = function() {
- callback(img);
- };
- img.src = url;
- };
- var loadImagesAsync = function(urls, callback) {
- var count = 1;
- var images = { };
- function countDown() {
- --count;
- if (count == 0) {
- callback(images);
- }
- }
- function imageLoaded(url) {
- return function(img) {
- images[url] = img;
- countDown();
- }
- }
- for (var ii = 0; ii < urls.length; ++ii) {
- ++count;
- loadImageAsync(urls[ii], imageLoaded(urls[ii]));
- }
- countDown();
- };
- return {
- create3DContext: create3DContext,
- create3DContextWithWrapperThatThrowsOnGLError:
- create3DContextWithWrapperThatThrowsOnGLError,
- checkCanvas: checkCanvas,
- checkCanvasRect: checkCanvasRect,
- createColoredTexture: createColoredTexture,
- drawQuad: drawQuad,
- glErrorShouldBe: glErrorShouldBe,
- fillTexture: fillTexture,
- loadImageAsync: loadImageAsync,
- loadImagesAsync: loadImagesAsync,
- loadProgram: loadProgram,
- loadProgramFromFile: loadProgramFromFile,
- loadProgramFromScript: loadProgramFromScript,
- loadShader: loadShader,
- loadShaderFromFile: loadShaderFromFile,
- loadShaderFromScript: loadShaderFromScript,
- loadStandardProgram: loadStandardProgram,
- loadStandardVertexShader: loadStandardVertexShader,
- loadStandardFragmentShader: loadStandardFragmentShader,
- loadTexture: loadTexture,
- setupProgram: setupProgram,
- setupSimpleTextureFragmentShader: setupSimpleTextureFragmentShader,
- setupSimpleTextureProgram: setupSimpleTextureProgram,
- setupSimpleTextureVertexShader: setupSimpleTextureVertexShader,
- setupTexturedQuad: setupTexturedQuad,
- setupUnitQuad: setupUnitQuad,
- setupWebGLWithShaders: setupWebGLWithShaders,
- shouldGenerateGLError: shouldGenerateGLError,
- readFile: readFile,
- none: false
- };
- }());
- function main() {
- var wtu = WebGLTestUtils;
- var canvas = document.getElementById("example");
- var gl = wtu.create3DContext(canvas);
- var program = wtu.setupTexturedQuad(gl);
- var tex = gl.createTexture();
- gl.enable(gl.BLEND);
- gl.disable(gl.DEPTH_TEST);
- wtu.fillTexture(gl, tex, 4096, 4096, [0, 192, 128, 255], 0);
- wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating texture");
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting texture params");
- var loc = gl.getUniformLocation(program, "tex");
- wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after getting tex locations");
- gl.uniform1i(loc, 0);
- wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting tex uniform");
- var numQuads = 100000;
- var indexBuf = new ArrayBuffer(numQuads * 6);
- var indices = new Uint8Array(indexBuf);
- for (var ii = 0; ii < numQuads; ++ii) {
- var offset = ii * 6;
- indices[offset + 0] = 0;
- indices[offset + 1] = 1;
- indices[offset + 2] = 2;
- indices[offset + 3] = 3;
- indices[offset + 4] = 4;
- indices[offset + 5] = 5;
- }
- var indexBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
- wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating index buffer");
- gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_BYTE, 0);
- wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
- successfullyParsed = true;
- }
- </script>
- </body>
- </html>
Add Comment
Please, Sign In to add comment