updating to glslCanvas.min.js

This commit is contained in:
Patricio Gonzalez Vivo 2015-07-14 10:34:43 -04:00
parent dc7679b56c
commit 2927a74370
28 changed files with 147 additions and 596 deletions

View File

@ -36,7 +36,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -36,7 +36,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -36,7 +36,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -35,7 +35,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -60,17 +60,17 @@ As a first step we need to know if the row of our thread is an even or odd numbe
____we have to fix these next two paragraphs together____
For that we are going to use ```fract()``` again but with the coordinates at the double of space. Take a look to the folowing formula and how it looks like.
For that we are going to use [```mod()```](../glossary/index.html#mod.md) of ```2.0``` and then see if the result is under ```1.0``` or not. Take a look to the folowing formula and uncomment the two last lines.
<div class="simpleFunction" data="y = fract(x*0.5);"></div>
<div class="simpleFunction" data="y = mod(x,2.0);
// y = mod(x,2.0) < 1.0 ? 0. : 1. ;
// y = step(1.0,mod(x,2.0));"></div>
By multiplying *x* by a half the space coordinate duplicate it size (which is the oposite of what we have been doing where we multiply the ```st``` and the space got shrinked). Let's say we are in position 1.0 (not even) we divide by two will be 0.5, while if the position was 2.0 (even) we devide by two the result will be 1.0. For values over 2.0, ```fract()``` will wrap them up and start again and again. This means the return value of this function will give numbers bellow 0.5 for not even numbers and above 0.5 for even. Isn't this super help full?
As you can see we can use a [ternary operator](https://en.wikipedia.org/wiki/%3F:) to check if the [```mod()```](../glossary/index.html#mod.md) of ```2.0``` is under ```1.0``` (second line) or similarly we can use a [```step()```](../glossary/index.html#step.md) function which does that the same operation, but faster. Why? Althogh is hard to know how each graphic card optimize and compiles the code is safe to assume that built-ins functions are faster than non-built-in one. Everytime you can use one, use it!
____fix the previous two paragraphs with Jen____
So now we have our even number formula we can apply some offset to odd rows to give a *brick* effect to our tiles. Check lines 14 the following code, there we are using the function we just describe "detect odd" rows and give them an offset on ```x``` of half of unit. Note that by multipling by ```0.0``` even will make the offset similiar to ```0.0``` so we don't add any offset. But on odd rows we multipliy the result of our function (```1.0```) to the offset of ```0.5``` to the ```x``` axis of the coordinate system.
Now we can apply some offset to odd rows to give a *brick* effect to our tiles. Check lines 14 and 15 of the following code, there we are using the function we just describe together with an ```if``` statement to detect even rows and give them an offset on ```x``` of half a space.
Note also that uncommenting line 34 will streach the aspect ration of the coordinate system to mimic the aspect of a "modern brick". As we did before by uncomenting line 42 you can see how the coordinate system looks maped on RED and GREEN.
Now try uncommenting line 32, this will streach the aspect ration of the coordinate system to mimic the aspect of a "modern brick". As we did before by uncomenting line 40 you can see how the coordinate system looks maped on RED and GREEN.
<div class="codeAndCanvas" data="bricks.frag"></div>
@ -98,7 +98,7 @@ Pay close attention to the function ```rotateTilePattern()```, which subdivides
<div class="codeAndCanvas" data="truchet.frag"></div>
* Comment, uncomment and duplicate lines 73 to 76 to compose new designs.
* Comment, uncomment and duplicate lines 69 to 72 to compose new designs.
* Change the black and white triangle for other element like: half cicles, rotated squares or lines.

View File

@ -11,9 +11,7 @@ vec2 brickTile(vec2 _st, float _zoom){
_st *= _zoom;
// Here is where the offset is happening
if (fract(_st.y * 0.5) > 0.5){
_st.x += 0.5;
}
_st.x += step(1., mod(_st.y,2.0)) * 0.5;
return fract(_st);
}

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -30,12 +30,8 @@ vec2 rotateTilePattern(vec2 _st){
// Give to each cell a index number
// acording to their position
float index = 0.0;
if (fract(_st.x * 0.5) > 0.5){
index += 1.0;
}
if (fract(_st.y * 0.5) > 0.5){
index += 2.0;
}
index += step(1., mod(_st.x,2.0));
index += step(1., mod(_st.y,2.0))*2.0;
// |
// 0 | 1

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -26,7 +26,7 @@
<script type="text/javascript" src="src/codemirror/mode/clike.js"></script>
<!-- GLSL Canvas -->
<script type="text/javascript" src="src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
<style>
body {
@ -74,8 +74,42 @@
loadTag()
}, false);
var editor;
var billboard;
var imgs = [];
function fetchHTTP(url, methood){
var request = new XMLHttpRequest(), response;
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
response = request.responseText;
}
}
request.open(methood ? methood : 'GET', url, false);
request.overrideMimeType("text/plain");
request.send(null);
return response;
}
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000/60);
};
})();
// Keep track of the mouse
var mouse = {x: 0, y: 0};
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
function removeElementsByClass(className){
var elements = document.getElementsByClassName(className);
while(elements.length > 0){
@ -133,25 +167,23 @@ void main(){\n\
}
var demoCanvas = document.getElementById("canvas");
if(demoCanvas && fragShader !== ""){
demoCanvas.setAttribute("data-fragment", fragShader);
console.log("data-fragment: " + fragFile);
if(imgs.length > 0){
if (demoCanvas && fragShader !== "") {
demoCanvas.setAttribute("data-fragment-url", fragFile);
if (imgs.length > 0) {
var textureList = "";
for(i in imgs){
for (i in imgs) {
textureList += imgs[i];
textureList += (i < imgs.length-1)?",":"";
}
demoCanvas.setAttribute("data-textures",textureList);
console.log("data-textures: " + textureList);
}
loadShaders();
billboard = new GlslCanvas(demoCanvas);
}
var demoEditor = document.getElementById("editor");
if(demoEditor){
var editor = CodeMirror(demoEditor,{
if (demoEditor) {
editor = CodeMirror(demoEditor,{
value: fragShader,
lineNumbers: true,
matchBrackets: true,
@ -166,15 +198,22 @@ void main(){\n\
editor.on("change", function() {
demoCanvas.setAttribute("data-fragment", editor.getValue());
loadShaders();
billboard.load(editor.getValue());
});
}
}
function render() {
billboard.setMouse(mouse)
billboard.render()
window.requestAnimFrame(render);
}
window.onload = function () {
loadTag();
renderShaders();
render();
};
</script>
</body>
</html>

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -26,7 +26,7 @@
<script type="text/javascript" src="src/codemirror/mode/clike.js"></script>
<!-- GLSL Canvas -->
<script type="text/javascript" src="src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
<style>
body {

View File

@ -37,7 +37,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="../css/style.css">
<script type="text/javascript" src="../src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</head>
<body>

View File

@ -35,7 +35,7 @@
<!-- My stuff -->
<link type='text/css' rel='stylesheet' href="css/style.css">
<script type="text/javascript" src="src/glslCanvas.js"></script>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
</style>
</head>

View File

@ -1,535 +0,0 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Patricio Gonzalez Vivo ( http://www.patriciogonzalezvivo.com )
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
var timeLoad = Date.now();
var mouse = {x: 0, y: 0};
var billboards = [];
function isCanvasVisible(_canvas){
return ((_canvas.getBoundingClientRect().top + _canvas.height) > 0) &&
(_canvas.getBoundingClientRect().top < (window.innerHeight || document.documentElement.clientHeight));
}
function isPowerOf2(value) {
return (value & (value - 1)) == 0;
};
function nextHighestPowerOfTwo(x) {
--x;
for (var i = 1; i < 32; i <<= 1) {
x = x | x >> i;
}
return x + 1;
}
function loadTexture(_gl, _texture) {
_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, _texture.image);
if (isPowerOf2(_texture.image.width) && isPowerOf2(_texture.image.height) ) {
_gl.generateMipmap(_gl.TEXTURE_2D);
_gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.LINEAR);
_gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR_MIPMAP_LINEAR);
} else {
_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);
_gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR);
}
_gl.bindTexture(_gl.TEXTURE_2D, null);
}
function getMousePos(_canvas, _evt) {
var rect = _canvas.getBoundingClientRect();
return {
x: _evt.clientX - rect.left,
y: _evt.clientY - rect.top
};
}
function loadShaders() {
var list = document.getElementsByTagName("canvas");
// Load canvas and WebGLContexta
for(var i = 0; i < list.length; i++){
var shaderSrc = { vertURL: null, vertSTR: null,
fragURL: null, fragSTR: null};
if( list[i].hasAttribute("data-fragment") ){
shaderSrc.fragSTR = list[i].getAttribute('data-fragment');
} else if( list[i].hasAttribute("data-fragment-url") ){
shaderSrc.fragURL = list[i].getAttribute('data-fragment-url');
} else {
continue;
}
var canvas = list[i];
var gl;
if( !billboards[i] || !billboards[i].gl){
console.log("Creating WebGL context");
gl = setupWebGL(list[i]);
} else {
gl = billboards[i].gl
}
var shader = loadShader(gl, shaderSrc);
if(!shader.program){
if(billboards[i].program){
shader.program = billboards[i].program;
} else {
billboards[i] = null;
return;
}
} else if ( billboards[i] && billboards[i].program ){
billboards[i].gl.deleteProgram(billboards[i].program);
}
var vbo = [];
if ( !billboards[i] || !billboards[i].vbo){
console.log("Creating Vbo");
// Define UVS buffer
var uvs;
var texCoordLocation = gl.getAttribLocation(shader.program, "a_texcoord");
uvs = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, uvs);
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array([0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 1.0,
1.0, 0.0,
1.0, 1.0]), gl.STATIC_DRAW);
gl.enableVertexAttribArray( texCoordLocation );
gl.vertexAttribPointer( texCoordLocation, 2, gl.FLOAT, false, 0, 0);
vbo.push(uvs);
// Define Vertex buffer
var vertices;
var positionLocation = gl.getAttribLocation(shader.program, "a_position");
vertices = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vertices);
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array([-1.0, -1.0,
1.0, -1.0,
-1.0, 1.0,
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0]), gl.STATIC_DRAW);
gl.enableVertexAttribArray( positionLocation );
gl.vertexAttribPointer( positionLocation , 2, gl.FLOAT, false, 0, 0);
vbo.push(vertices);
} else {
vbo = billboards[i].vbo;
}
// Clean texture
var textures = [];
// Need to load textures
var bLoadTextures = list[i].hasAttribute('data-textures');
if ( billboards[i] && billboards[i].textures && bLoadTextures){
var nImages = canvas.getAttribute('data-textures').split(',');
if (nImages.length === billboards[i].textures.length){
bLoadTextures = false;
for(var j in nImages){
if( billboards[i].textures[j].image.getAttribute("src") !== nImages[j] ){
bLoadTextures = true;
break;
}
}
}
if (!bLoadTextures){
textures = billboards[i].textures;
}
}
if( bLoadTextures ){
// Clean the texture array
while(textures.length > 0) {
console.log("Deleting texture: " + (textures.length-1));
gl.deleteTexture(textures[textures.length-1]);
textures.pop();
}
var imgList = list[i].getAttribute('data-textures').split(',');
for(var nImg in imgList){
console.log("Loading texture: " + imgList[nImg]);
textures.push(gl.createTexture());
gl.bindTexture(gl.TEXTURE_2D, textures[nImg]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 255, 0, 255])); // red
textures[nImg].image = new Image();
textures[nImg].image.onload = function(_canvas,_gl,_program,_textures,_tex) {
return function() {
loadTexture(_gl, _tex);
render(_canvas, _gl, _program, _textures)
};
}(canvas,gl,shader.program, textures, textures[nImg]);
textures[nImg].image.src = imgList[nImg];
}
}
// Assign canvas, gl context, shader, UV/Verts buffers and animate boolean to billboard
billboards[i] = { canvas: canvas,
gl: gl,
program: shader.program,
vbo: vbo,
textures: textures,
mouse: mouse,
animated: shader.animated };
renderShader( billboards[i] );
}
}
function renderShaders(){
for(var i = 0; i < billboards.length; i++){
// If there is something on the billboard
if( billboards[i] !== undefined ){
if ( billboards[i].animated === true &&
isCanvasVisible(billboards[i].canvas )){
renderShader( billboards[i] );
}
}
}
window.requestAnimFrame(renderShaders);
}
/**
* 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 '' +
'<table style="background-color: #8CE; width: 100%; height: 100%;"><tr>' +
'<td align="center">' +
'<div style="display: table-cell; vertical-align: middle;">' +
'<div style="">' + msg + '</div>' +
'</div>' +
'</td></tr></table>';
};
/**
* Mesasge for getting a webgl browser
* @type {string}
*/
var GET_A_WEBGL_BROWSER = '' +
'This page requires a browser that supports WebGL.<br/>' +
'<a href="http://get.webgl.org">Click here to upgrade your browser.</a>';
/**
* Mesasge for need better hardware
* @type {string}
*/
var OTHER_PROBLEM = '' +
"It doesn't appear your computer can support WebGL.<br/>" +
'<a href="http://get.webgl.org/troubleshooting/">Click here for more information.</a>';
/**
* Creates a webgl context. If creation fails it will
* change the contents of the container of the <canvas>
* tag to an error message with the correct links for WebGL.
* @param {Element} 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.
*/
function setupWebGL (_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);
}
context.getExtension('OES_standard_derivatives');
return context;
};
/**
* Creates a webgl context.
* @param {!Canvas} canvas The canvas tag to get context
* from. If one is not passed in one will be created.
* @return {!WebGLContext} The created context.
*/
function create3DContext(_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;
}
/**
* Loads a shader.
* @param {!WebGLContext} gl The WebGLContext 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.
*/
function createProgram(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);
// Check the link status
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
// something went wrong with the link
lastError = gl.getProgramInfoLog (program);
console.log("Error in program linking:" + lastError);
gl.deleteProgram(program);
return null;
}
return program;
};
/*
* Fetch for files
*/
function fetchHTTP(url, methood){
var request = new XMLHttpRequest(), response;
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
response = request.responseText;
}
}
request.open(methood ? methood : 'GET', url, false);
request.overrideMimeType("text/plain");
request.send();
return response;
}
/*
* Create a Vertex of a specific type (gl.VERTEX_SHADER/)
*/
function createShader(_gl, _source, _type) {
var shader = _gl.createShader( _type );
_gl.shaderSource(shader, _source);
_gl.compileShader(shader);
var compiled = _gl.getShaderParameter(shader, _gl.COMPILE_STATUS);
if (!compiled) {
// Something went wrong during compilation; get the error
lastError = _gl.getShaderInfoLog(shader);
console.error("*** Error compiling shader '" + shader + "':" + lastError);
_gl.deleteShader(shader);
return null;
}
return shader;
}
/*
* Loads the vert/frag Shaders
*/
function loadShader( _gl, _shaderSrc ) {
var vertString = "";
if(_shaderSrc.vertURL){
vertString = fetchHTTP( _shaderSrc.vertURL );
} else {
vertString = "precision mediump float;\n\
uniform vec2 u_resolution;\n\
uniform float u_time;\n\
attribute vec2 a_position;\n\
attribute vec2 a_texcoord;\n\
varying vec2 v_texcoord;\n\
void main() {\n\
gl_Position = vec4(a_position, 0.0, 1.0);\n\
v_texcoord = a_texcoord;\n\
}";
}
var fragString = "";
if (_shaderSrc.fragSTR){
fragString += _shaderSrc.fragSTR;
} else if(_shaderSrc.fragURL){
fragString += fetchHTTP( _shaderSrc.fragURL );
} else {
fragString += "uniform vec2 u_resolution;\n\
uniform float u_time;\n\
varying vec2 v_texcoord;\n\
void main(){\n\
vec2 st = gl_FragCoord.xy/u_resolution;\n\
gl_FragColor = vec4(st.x,st.y,abs(sin(u_time)),1.0);\n\
}";
}
var animated = false;
var nTimes = (fragString.match(/u_time/g)|| []).length;
var nMouse = (fragString.match(/u_mouse/g)|| []).length;
animated = ((nTimes > 1) || (nMouse > 1));
var vertexShader = createShader(_gl, vertString, _gl.VERTEX_SHADER);
var fragmentShader = createShader(_gl, fragString , _gl.FRAGMENT_SHADER);
if(!fragmentShader){
fragmentShader = createShader(_gl, "void main(){\n\
gl_FragColor = vec4(1.0);\n\
}" , _gl.FRAGMENT_SHADER);
}
// Create and use program
var program = createProgram( _gl, [vertexShader, fragmentShader]);
_gl.useProgram(program);
// Delete shaders
_gl.detachShader(program, vertexShader);
_gl.detachShader(program, fragmentShader);
_gl.deleteShader(vertexShader);
_gl.deleteShader(fragmentShader);
return {'program': program,
'animated': animated};
}
function FormatNumberLength(_num, _length) {
var r = "" + _num;
while (r.length < _length) {
r = "0" + r;
}
return r;
}
/*
* Render loop of shader in a canvas
*/
function renderShader( _billboard ) {
render(_billboard.canvas, _billboard.gl, _billboard.program, _billboard.textures);
}
function render(_canvas, _gl, _program, _textures) {
if (!_gl) {
return;
}
// set the time uniform
var timeFrame = Date.now();
var time = (timeFrame-timeLoad) / 1000.0;
var timeLocation = _gl.getUniformLocation(_program, "u_time");
_gl.uniform1f(timeLocation, time);
// set the mouse uniform
var rect = _canvas.getBoundingClientRect();
if( mouse.x >= rect.left &&
mouse.x <= rect.right &&
mouse.y >= rect.top &&
mouse.y <= rect.bottom){
var mouseLocation = _gl.getUniformLocation(_program, "u_mouse");
_gl.uniform2f(mouseLocation,mouse.x-rect.left,_canvas.height-(mouse.y-rect.top));
}
// set the resolution uniform
var resolutionLocation = _gl.getUniformLocation(_program, "u_resolution");
_gl.uniform2f(resolutionLocation, _canvas.width, _canvas.height);
for (var i = 0; i < _textures.length; ++i){
_gl.uniform1i( _gl.getUniformLocation( _program, "u_tex"+i), i);
_gl.uniform2f( _gl.getUniformLocation( _program, "u_tex"+i+"Resolution"),
_textures[i].image.width,
_textures[i].image.height);
_gl.activeTexture(_gl.TEXTURE0+i);
_gl.bindTexture(_gl.TEXTURE_2D, _textures[i]);
}
// Draw the rectangle.
_gl.drawArrays(_gl.TRIANGLES, 0, 6);
// console.log("Render " + time);
}
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
/**
* Provides requestAnimationFrame in a cross browser way.
*/
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000/60);
};
})();
/**
* Provides cancelRequestAnimationFrame in a cross browser way.
*/
window.cancelRequestAnimFrame = (function() {
return window.cancelCancelRequestAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
window.oCancelRequestAnimationFrame ||
window.msCancelRequestAnimationFrame ||
window.clearTimeout;
})();

View File

@ -130,6 +130,7 @@ function randomString(length, chars) {
return result;
}
var billboards = {};
function loadMarkdown(){
// parse MARKDOWN
@ -160,7 +161,7 @@ function loadMarkdown(){
// load code
str = fetchHTTP(srcFile);
inject = '<div class="editor">\
<canvas id ='+id+' class="canvas" data-fragment="'+str+'" ';
<canvas id ='+id+' class="canvas" data-fragment-url="'+srcFile+'" ';
// load images
imagesFiles = ccList[i].getAttribute("data-imgs");
@ -218,9 +219,8 @@ function loadMarkdown(){
});
editor.on("change", function(cm, change) {
var canvasToChange = document.getElementById(cm.id);
canvasToChange.setAttribute("data-fragment", cm.getValue());
loadShaders();
billboards[cm.id].load(cm.getValue());
billboards[cm.id].render(true);
});
}
}
@ -257,9 +257,8 @@ function loadMarkdown(){
editor.id = id;
editor.on("change", function(cm, change) {
var canvasToChange = document.getElementById(cm.id);
canvasToChange.setAttribute("data-fragment", preFunction+cm.getValue()+postFunction);
loadShaders();
billboards[cm.id].load(preFunction+cm.getValue()+postFunction);
billboards[cm.id].render(true);
});
}
}
@ -278,6 +277,27 @@ function loadMarkdown(){
}
}
var canvasCounter = 0;
function loadCanvas() {
var canvas = document.getElementsByClassName("canvas");
for (var i = 0; i < canvas.length; i++){
// Initialize the GL context
if (canvas[i].id === "custom") {
canvas[i].id = canvas[i].id + " ID" + String(canvasCounter++);
}
billboards[canvas[i].id] = new GlslCanvas(canvas[i]);
}
}
function renderCanvas() {
var IDs = Object.keys(billboards);
for(var i = 0; i < IDs.length; i++){
billboards[IDs[i]].setMouse(mouse);
billboards[IDs[i]].render();
}
window.requestAnimFrame(renderCanvas);
}
function insertAfter(newElement,targetElement) {
var parent = targetElement.parentNode;
if (parent.lastChild == targetElement) {
@ -364,10 +384,43 @@ function nextPage(){
window.location.href = url;
}
// Keep track of the mouse
var mouse = {x: 0, y: 0};
document.addEventListener('mousemove', function(e){
mouse.x = e.clientX || e.pageX;
mouse.y = e.clientY || e.pageY
}, false);
/**
* Provides requestAnimationFrame in a cross browser way.
*/
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
return window.setTimeout(callback, 1000/60);
};
})();
/**
* Provides cancelRequestAnimationFrame in a cross browser way.
*/
window.cancelRequestAnimFrame = (function() {
return window.cancelCancelRequestAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
window.oCancelRequestAnimationFrame ||
window.msCancelRequestAnimationFrame ||
window.clearTimeout;
})();
window.onload = function(){
loadMarkdown();
captionizeImages();
loadShaders();
renderShaders();
};
loadCanvas();
renderCanvas();
};