diff --git a/_assets/javascript/shaderCanvas.js b/_assets/javascript/shaderCanvas.js new file mode 100644 index 0000000..2e9d113 --- /dev/null +++ b/_assets/javascript/shaderCanvas.js @@ -0,0 +1,50 @@ +// STEP 1: Prepare the canvas and get WebGL context +var vertShaderSource = document.getElementById("vertex-shader").text; +var fragShaderSource = document.getElementById("fragment-shader").text; +var canvas = document.getElementById('shader-canvas'); +var gl = canvas.getContext('webgl', { + antialias: false, + depth: false +}); +// STEP 2: define geometry and store it in buffer objects +var verticies = [-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0]; +var vertex_buffer = gl.createBuffer(); +gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); +gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticies), gl.STATIC_DRAW); +gl.bindBuffer(gl.ARRAY_BUFFER, null) +// STEP 3: Create and compile shader programs +// Vert shader: +//var vertCode = +// 'attribute vec2 coordinates;' + +// 'void main(void) {' + +// ' gl_Position = vec4(coordinates, 0.0, 1.0);' + +// '}'; +var vertCode = vertShaderSource; +var vertShader = gl.createShader(gl.VERTEX_SHADER); +gl.shaderSource(vertShader, vertCode); +gl.compileShader(vertShader); +// Frag shader: +// var fragCode = 'void main(void) {' + + // 'gl_FragColor = vec4(0.0, 0.3, 0.5, 1.0);' + +// '}'; +var fragCode = fragShaderSource; +var fragShader = gl.createShader(gl.FRAGMENT_SHADER); +gl.shaderSource(fragShader, fragCode); +gl.compileShader(fragShader); +// combine shaders: +var shaderProgram = gl.createProgram(); +gl.attachShader(shaderProgram, vertShader); +gl.attachShader(shaderProgram, fragShader); +gl.linkProgram(shaderProgram); +gl.useProgram(shaderProgram); +// STEP 4: Associate the shader program to buffer objects +gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); +var coord = gl.getAttribLocation(shaderProgram, "coordinates"); +gl.vertexAttribPointer(coord, 2, gl.FLOAT, false, 0, 0); +gl.enableVertexAttribArray(coord); +// STEP 5: Draw the object: +gl.clearColor(0.0, 0.0, 0.0, 1.0); +gl.enable(gl.DEPTH_TEST); +gl.clear(gl.COLOR_BUFFER_BIT); +gl.viewport(0, 0, canvas.width, canvas.height); +gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); diff --git a/_assets/javascript/shaderCanvas2.js b/_assets/javascript/shaderCanvas2.js new file mode 100644 index 0000000..1e3c100 --- /dev/null +++ b/_assets/javascript/shaderCanvas2.js @@ -0,0 +1,760 @@ +/* + * Copyright 2012, Gregg Tavares. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Gregg Tavares. nor the names of his + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +"use strict"; + +/** @module webgl-utils */ +// These funcitions are meant solely to help unclutter the tutorials. +// They are not meant as production type functions. + +//(function() { + +/** + * Wrapped logging function. + * @param {string} msg The message to log. + */ +var log = function(msg) { + if (window.console && window.console.log) { + window.console.log(msg); + } +}; + +/** + * Wrapped logging function. + * @param {string} msg The message to log. + */ +var error = function(msg) { + if (window.console) { + if (window.console.error) { + window.console.error(msg); + } + else if (window.console.log) { + window.console.log(msg); + } + } +}; + +/** + * Turn off all logging. + */ +var loggingOff = function() { + log = function() {}; + error = function() {}; +}; + +/** + * Check if the page is embedded. + * @return {boolean} True of we are in an iframe + */ +var isInIFrame = function() { + return window != window.top; +}; + +/** + * Converts a WebGL enum to a string + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {number} value The enum value. + * @return {string} The enum as a string. + */ +var glEnumToString = function(gl, value) { + for (var p in gl) { + if (gl[p] == value) { + return p; + } + } + return "0x" + value.toString(16); +}; + +/** + * Creates the HTLM for a failure message + * @param {string} canvasContainerId id of container of th + * canvas. + * @return {string} The html. + */ +var makeFailHTML = function(msg) { + return '' + + '' + + '
' + + '
' + + '
' + msg + '
' + + '
' + + '
'; +}; + +/** + * Mesasge for getting a webgl browser + * @type {string} + */ +var GET_A_WEBGL_BROWSER = '' + + 'This page requires a browser that supports WebGL.
' + + 'Click here to upgrade your browser.'; + +/** + * Mesasge for need better hardware + * @type {string} + */ +var OTHER_PROBLEM = '' + + "It doesn't appear your computer can support WebGL.
" + + 'Click here for more information.'; + +/** + * Creates a webgl context. If creation fails it will + * change the contents of the container of the + * tag to an error message with the correct links for WebGL. + * @param {HTMLCanvasElement} canvas. The canvas element to + * create a context from. + * @param {WebGLContextCreationAttirbutes} opt_attribs Any + * creation attributes you want to pass in. + * @return {WebGLRenderingContext} The created context. + */ +var setupWebGL = function(canvas, opt_attribs) { + function showLink(str) { + var container = canvas.parentNode; + if (container) { + container.innerHTML = makeFailHTML(str); + } + }; + + if (!window.WebGLRenderingContext) { + showLink(GET_A_WEBGL_BROWSER); + return null; + } + + var context = create3DContext(canvas, opt_attribs); + if (!context) { + showLink(OTHER_PROBLEM); + } + return context; +}; + +/** + * Creates a webgl context. + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +var create3DContext = function(canvas, opt_attribs) { + var names = ["webgl", "experimental-webgl"]; + var context = null; + for (var ii = 0; ii < names.length; ++ii) { + try { + context = canvas.getContext(names[ii], opt_attribs); + } catch(e) {} + if (context) { + break; + } + } + return context; +} + +var updateCSSIfInIFrame = function() { + if (isInIFrame()) { + document.body.className = "iframe"; + } +}; + +/** + * Gets a WebGL context. + * makes its backing store the size it is displayed. + */ +var getWebGLContext = function(canvas, opt_attribs, opt_options) { + var options = opt_options || {} + + if (isInIFrame()) { + updateCSSIfInIFrame(); + + // make the canvas backing store the size it's displayed. + if (!options.dontResize) { + var width = canvas.clientWidth; + var height = canvas.clientHeight; + canvas.width = width; + canvas.height = height; + } + } else { + var title = document.title; + var h1 = document.createElement("h1"); + h1.innerText = title; + document.body.insertBefore(h1, document.body.children[0]); + } + + var gl = setupWebGL(canvas, opt_attribs); + return gl; +}; + +/** + * Loads a shader. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {string} shaderSource The shader source. + * @param {number} shaderType The type of shader. + * @param {function(string): void) opt_errorCallback callback for errors. + * @return {WebGLShader} The created shader. + */ +var loadShader = function(gl, shaderSource, shaderType, opt_errorCallback) { + var errFn = opt_errorCallback || error; + // Create the shader object + var shader = gl.createShader(shaderType); + + // Load the shader source + gl.shaderSource(shader, shaderSource); + + // Compile the shader + gl.compileShader(shader); + + // Check the compile status + var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + var lastError = gl.getShaderInfoLog(shader); + errFn("*** Error compiling shader '" + shader + "':" + lastError); + gl.deleteShader(shader); + return null; + } + + return shader; +} + +/** + * Creates a program, attaches shaders, binds attrib locations, links the + * program and calls useProgram. + * @param {WebGLShader[]} shaders The shaders to attach + * @param {string[]?} opt_attribs The attribs names. + * @param {number[]?} opt_locations The locations for the + * attribs. + * @param {function(string): void) opt_errorCallback callback for errors. + */ +var loadProgram = function( + gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { + var errFn = opt_errorCallback || error; + 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); + + // Check the link status + var linked = gl.getProgramParameter(program, gl.LINK_STATUS); + if (!linked) { + // something went wrong with the link + var lastError = gl.getProgramInfoLog (program); + errFn("Error in program linking:" + lastError); + + gl.deleteProgram(program); + return null; + } + return program; +}; + +/** + * Loads a shader from a script tag. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {string} scriptId The id of the script tag. + * @param {number} opt_shaderType The type of shader. If not passed in it will + * be derived from the type of the script tag. + * @param {function(string): void) opt_errorCallback callback for errors. + * @return {WebGLShader} The created shader. + */ +var createShaderFromScript = function( + gl, scriptId, opt_shaderType, opt_errorCallback) { + 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, + opt_errorCallback); +}; + +var defaultShaderType = [ + "VERTEX_SHADER", + "FRAGMENT_SHADER" +]; + +/** + * Creates a program from 2 script tags. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderScriptIds Array of ids of the script + * tags for the shaders. The first is assumed to be the + * vertex shader, the second the fragment shader. + * @param {string[]?} opt_attribs The attribs names. + * @param {number[]?} opt_locations The locations for the + * attribs. + * @param {function(string): void) opt_errorCallback callback for errors. + * @return {WebGLProgram} The created program. + */ +var createProgramFromScripts = function( + gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { + var shaders = []; + for (var ii = 0; ii < shaderScriptIds.length; ++ii) { + shaders.push(createShaderFromScript( + gl, shaderScriptIds[ii], gl[defaultShaderType[ii]], opt_errorCallback)); + } + return loadProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback); +}; + +/** + * Creates a program from 2 sources. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSourcess Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {string[]?} opt_attribs The attribs names. + * @param {number[]?} opt_locations The locations for the + * attribs. + * @param {function(string): void) opt_errorCallback callback for errors. + * @return {WebGLProgram} The created program. + */ +var createProgramFromSources = function( + gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + var shaders = []; + for (var ii = 0; ii < shaderSources.length; ++ii) { + shaders.push(loadShader( + gl, shaderSources[ii], gl[defaultShaderType[ii]], opt_errorCallback)); + } + return loadProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback); +}; + +/** + * Returns the corresponding bind point for a given sampler type + */ +var getBindPointForSamplerType = function(gl, type) { + if (type == gl.SAMPLER_2D) return gl.TEXTURE_2D; + if (type == gl.SAMPLER_CUBE) return gl.TEXTURE_CUBE_MAP; +}; + +/** + * @typedef {Object.} Setters + */ + +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see setUniforms for example + * + * @param {WebGLProgram} program the program to create setters + * for. + * @returns {Setters} an object with a setter for each uniform + * by name. + */ +var createUniformSetters = function(gl, program) { + var textureUnit = 0; + + /** + * Creates a setter for a uniform of the given program with it's + * location embedded in the setter. + * @param {WebGLProgram} program + * @param {WebGLUniformInfo} uniformInfo + * @returns {function} the created setter. + */ + var createUniformSetter = function(program, uniformInfo) { + var location = gl.getUniformLocation(program, uniformInfo.name); + var type = uniformInfo.type; + // Check if this uniform is an array + var isArray = (uniformInfo.size > 1 && uniformInfo.name.substr(-3) == "[0]"); + if (type == gl.FLOAT && isArray) + return function(v) { gl.uniform1fv(location, v); }; + if (type == gl.FLOAT) + return function(v) { gl.uniform1f(location, v); }; + if (type == gl.FLOAT_VEC2) + return function(v) { gl.uniform2fv(location, v); }; + if (type == gl.FLOAT_VEC3) + return function(v) { gl.uniform3fv(location, v); }; + if (type == gl.FLOAT_VEC4) + return function(v) { gl.uniform4fv(location, v); }; + if (type == gl.INT && isArray) + return function(v) { gl.uniform1iv(location, v); }; + if (type == gl.INT) + return function(v) { gl.uniform1i(location, v); }; + if (type == gl.INT_VEC2) + return function(v) { gl.uniform2iv(location, v); }; + if (type == gl.INT_VEC3) + return function(v) { gl.uniform3iv(location, v); }; + if (type == gl.INT_VEC4) + return function(v) { gl.uniform4iv(location, v); }; + if (type == gl.BOOL) + return function(v) { gl.uniform1iv(location, v); }; + if (type == gl.BOOL_VEC2) + return function(v) { gl.uniform2iv(location, v); }; + if (type == gl.BOOL_VEC3) + return function(v) { gl.uniform3iv(location, v); }; + if (type == gl.BOOL_VEC4) + return function(v) { gl.uniform4iv(location, v); }; + if (type == gl.FLOAT_MAT2) + return function(v) { gl.uniformMatrix2fv(location, false, v); }; + if (type == gl.FLOAT_MAT3) + return function(v) { gl.uniformMatrix3fv(location, false, v); }; + if (type == gl.FLOAT_MAT4) + return function(v) { gl.uniformMatrix4fv(location, false, v); }; + if ((type == gl.SAMPLER_2D || type == gl.SAMPLER_CUBE) && isArray) { + var units = []; + for (var ii = 0; ii < info.size; ++ii) { + units.push(textureUnit++); + } + return function(bindPoint, units) { + return function(textures) { + gl.uniform1iv(location, units); + textures.forEach(function(texture, index) { + gl.activeTexture(gl.TEXTURE0 + units[index]); + gl.bindTexture(bindPoint, tetxure); + }); + } + }(getBindPointForSamplerType(gl, type), units); + } + if (type == gl.SAMPLER_2D || type == gl.SAMPLER_CUBE) + return function(bindPoint, unit) { + return function(texture) { + gl.uniform1i(location, unit); + gl.activeTexture(gl.TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + }; + }(getBindPointForSamplerType(gl, type), textureUnit++); + throw ("unknown type: 0x" + type.toString(16)); // we should never get here. + }; + + var uniformSetters = { }; + var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + + for (var ii = 0; ii < numUniforms; ++ii) { + var uniformInfo = gl.getActiveUniform(program, ii); + if (!uniformInfo) { + break; + } + var name = uniformInfo.name; + // remove the array suffix. + if (name.substr(-3) == "[0]") { + name = name.substr(0, name.length - 3); + } + var setter = createUniformSetter(program, uniformInfo); + uniformSetters[name] = setter; + } + return uniformSetters; +}; + +/** + * Set uniforms and binds related textures. + * + * @example + * + * var program = createProgramFromScripts( + * gl, ["some-vs", "some-fs"); + * + * var uniformSetters = createUniformSetters(program); + * + * var tex1 = gl.createTexture(); + * var tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * var uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * u_someColor: [1,0,0,1], + * u_somePosition: [0,1,1], + * u_someMatrix: [ + * 1,0,0,0, + * 0,1,0,0, + * 0,0,1,0, + * 0,0,0,0, + * ], + * } + * + * gl.useProgram(program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * setUniforms(uniformSetters, uniforms); + * + * @param {Setters} setters the setters returned from + * createUniformSettersForProgram + * @param {Object.} an object with values for the + * uniforms. + */ +var setUniforms = function(setters, values) { + Object.keys(values).forEach(function(name) { + var setter = setters[name]; + if (setter) { + setter(values[name]); + } + }); +}; + +/** + * Creates setter functions for all attributes of a shader + * program + * + * @see setAttributes for example + * + * @param {WebGLProgram} program the program to create setters + * for. + * @returns {Setters} an object with a setter for each uniform + * by name. + */ +var createAttributeSetters = function(gl, program) { + var attribSetters = { + }; + + function createAttribSetter(index) { + return function(b) { + gl.bindBuffer(gl.ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribPointer( + index, b.numComponents || b.size, b.type || gl.FLOAT, b.normalize || false, b.stride || 0, b.offset || 0); + }; + } + + var numAttribs = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); + for (var ii = 0; ii < numAttribs; ++ii) { + var attribInfo = gl.getActiveAttrib(program, ii); + if (!attribInfo) { + break; + } + var index = gl.getAttribLocation(program, attribInfo.name); + attribSetters[attribInfo.name] = createAttribSetter(index); + } + + return attribSetters; +}; + +/** + * Sets attributes and binds buffers. + * + * @example + * + * var program = createProgramFromScripts( + * gl, ["some-vs", "some-fs"); + * + * var attribSetters = createAttributeSetters(program); + * + * var positionBuffer = gl.createBuffer(); + * var texcoordBuffer = gl.createBuffer(); + * + * var attribs = { + * a_position: {buffer: positionBuffer, numComponents: 3}, + * a_texcoord: {buffer: texcoordBuffer, numComponents: 2}, + * }; + * + * gl.useProgram(program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setAttributes(attribSetters, attribs); + * + * Properties of attribs. For each attrib you can add + * properties: + * + * type: the type of data in the buffer. Default = gl.FLOAT + * normalize: whether or not to normalize the data. Default = + * false + * stride: the stride. Default = 0 + * offset: offset into the buffer. Default = 0 + * + * For example if you had 3 value float positions, 2 value + * float texcoord and 4 value uint8 colors you'd setup your + * attribs like this + * + * var attribs = { + * a_position: {buffer: positionBuffer, numComponents: 3}, + * a_texcoord: {buffer: texcoordBuffer, numComponents: 2}, + * a_color: { + * buffer: colorBuffer, + * numComponents: 4, + * type: gl.UNSIGNED_BYTE, + * normalize: true, + * }, + * }; + * + */ +var setAttributes = function(setters, buffers) { + Object.keys(buffers).forEach(function(name) { + var setter = setters[name]; + if (setter) { + setter(buffers[name]); + } + }); +}; + +// Add your prefix here. +var browserPrefixes = [ + "", + "MOZ_", + "OP_", + "WEBKIT_" +]; + +/** + * Given an extension name like WEBGL_compressed_texture_s3tc + * returns the supported version extension, like + * WEBKIT_WEBGL_compressed_teture_s3tc + * @param {string} name Name of extension to look for + * @return {WebGLExtension} The extension or undefined if not + * found. + */ +var getExtensionWithKnownPrefixes = function(gl, name) { + for (var ii = 0; ii < browserPrefixes.length; ++ii) { + var prefixedName = browserPrefixes[ii] + name; + var ext = gl.getExtension(prefixedName); + if (ext) { + return ext; + } + } +}; + + +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {boolean} true if the canvas was resized. + */ +var resizeCanvasToDisplaySize = function(canvas) { + var width = canvas.clientWidth; + var height = canvas.clientHeight; + if (canvas.width != width || + canvas.height != height) { + canvas.width = width; + canvas.height = height; + return true; + } + return false; +} + +/* export functions */ +window.createAttributeSetters = createAttributeSetters; +window.createProgram = loadProgram; +window.createProgramFromScripts = createProgramFromScripts; +window.createProgramFromSources = createProgramFromSources; +window.createShaderFromScriptElement = createShaderFromScript; +window.createUniformSetters = createUniformSetters; +window.getWebGLContext = getWebGLContext; +window.updateCSSIfInIFrame = updateCSSIfInIFrame; +window.getExtensionWithKnownPrefixes = getExtensionWithKnownPrefixes; +window.resizeCanvasToDisplaySize = resizeCanvasToDisplaySize; +window.setAttributes = setAttributes; +window.setUniforms = setUniforms; +window.setupWebGL = setupWebGL; + +// All browsers that support WebGL support requestAnimationFrame +window.requestAnimFrame = window.requestAnimationFrame; // just to stay backward compatible. +window.cancelRequestAnimFrame = window.cancelAnimationFrame; // just to stay backward compatible. + +//}()); + + + +function onLoad () { + var canvas = document.getElementById("canvas"); + var gl = canvas.getContext("experimental-webgl"); + + var vertexShaderNode = createShaderFromScriptElement(gl, "node-vertex-shader"); + var fragmentShaderNode = createShaderFromScriptElement(gl, "node-fragment-shader"); + var programNode = createProgram(gl, [vertexShaderNode, fragmentShaderNode]); + gl.useProgram(programNode); + + + var ATTRIBUTES = 5; + var j = 0; + var data = []; + var circle = {x: 50, y: 50, r: 45}; + + data[j++] = (circle.x - circle.r); + data[j++] = (circle.y - circle.r); + data[j++] = circle.x; + data[j++] = circle.y; + data[j++] = circle.r; + + data[j++] = (circle.x + (1 + Math.sqrt(2)) * circle.r); + data[j++] = circle.y - circle.r; + data[j++] = circle.x; + data[j++] = circle.y; + data[j++] = circle.r; + + data[j++] = (circle.x - circle.r); + data[j++] = (circle.y + (1 + Math.sqrt(2)) * circle.r); + data[j++] = circle.x; + data[j++] = circle.y; + data[j++] = circle.r; + + var dataBuffer = new Float32Array(data); + + var buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData( + gl.ARRAY_BUFFER, + dataBuffer, + gl.STATIC_DRAW); + + var resolutionLocation = gl.getUniformLocation(programNode, "u_resolution"); + gl.uniform2f(resolutionLocation, canvas.width, canvas.height); + + var positionLocation = gl.getAttribLocation(programNode, "a_position"); + var centerLocation = gl.getAttribLocation(programNode, "a_center"); + var radiusLocation = gl.getAttribLocation(programNode, "a_radius"); + + + gl.enableVertexAttribArray(positionLocation); + gl.enableVertexAttribArray(centerLocation); + gl.enableVertexAttribArray(radiusLocation); + + gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0); + gl.vertexAttribPointer(centerLocation, 2, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 8); + gl.vertexAttribPointer(radiusLocation, 1, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 16); + + gl.drawArrays(gl.TRIANGLES, 0, data.length/ATTRIBUTES); + } +onLoad(); diff --git a/_posts/2020-12-18-shader.markdown b/_posts/2020-12-18-shader.markdown new file mode 100644 index 0000000..b256680 --- /dev/null +++ b/_posts/2020-12-18-shader.markdown @@ -0,0 +1,57 @@ +--- +layout: post-plain +title: "Shader fun" +date: 2020-12-28 +categories: design +--- + + + + + + + +{% asset shaderCanvas2.js %} diff --git a/assets/myShader.frag b/assets/myShader.frag new file mode 100644 index 0000000..c6fa9b5 --- /dev/null +++ b/assets/myShader.frag @@ -0,0 +1,3 @@ +void main(void) { + gl_FragColor = vec4(0.5, 0.3, 0.0, 1.0); + }