line rendering in webgl

pull/5/head
Igor Null 2015-08-30 10:01:15 +00:00
commit 870af9bfa6
2 zmienionych plików z 221 dodań i 0 usunięć

44
gl.js 100644
Wyświetl plik

@ -0,0 +1,44 @@
var CreateShader = function(gl, vsSource, fsSource) {
'use strict';
if (typeof WebGLRenderingContext !== 'function' ||
!(gl instanceof WebGLRenderingContext)) {
throw new Error('CreateShader: no WebGL context');
}
let vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, vsSource);
gl.compileShader(vs);
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
let infoLog = gl.getShaderInfoLog(vs);
gl.deleteShader(vs);
throw new Error('CreateShader, vertex shader compilation:\n' + infoLog);
}
let fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fs, fsSource);
gl.compileShader(fs);
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
let infoLog = gl.getShaderInfoLog(fs);
gl.deleteShader(vs);
gl.deleteShader(fs);
throw new Error('CreateShader, fragment shader compilation:\n' + infoLog);
}
let program = gl.createProgram();
gl.attachShader(program, vs);
gl.deleteShader(vs);
gl.attachShader(program, fs);
gl.deleteShader(fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
let infoLog = gl.getProgramInfoLog(program);
gl.deleteProgram(program);
throw new Error('CreateShader, linking:\n' + infoLog);
}
return program;
};

177
index.html 100644
Wyświetl plik

@ -0,0 +1,177 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>woscilloscope</title>
<script src="base64.js"></script>
<script src="algebra.js"></script>
<script src="gl.js"></script>
<script>
window.onload = function() {
'use strict';
let canvas = $('c'),
gl = initGl(canvas),
shader = CreateShader(gl, getText('vshader'), getText('fshader'));
points = makePoints(gl);
ilaced = makeInterlaced(gl);
let loop = function() {
draw(gl, shader);
requestAnimationFrame(loop);
}
loop();
};
var points = null;
var ilaced = null;
function initGl(canvas) {
'use strict';
let gl = canvas.getContext('webgl');
gl.clearColor( 0.0, 0.0, 0.0, 1.0 );
gl.viewport(0, 0, canvas.width, canvas.height);
return gl;
}
function makeInterlaced(gl) {
'use strict';
let interlaced = new Int32Array(4096/4);
for (let i = interlaced.length; i--; ) {
interlaced[i] = 0xFF01FF01;
}
let vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, interlaced, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
return vbo;
}
function makePoints(gl) {
'use strict';
let vertices = [],
TAU = Math.PI*2;
for (let i = 0; i < 100; i++) {
let ph = i / 100 * 2 * TAU;
let r = 0.0023 * Math.exp(0.5*ph);
vertices.push(Math.cos(ph)*r, Math.sin(ph)*r);
}
vertices = vertices.map(function(e) { return (e)*32767; });
vertices = new Int16Array(vertices);
let inView = new Int32Array(vertices.buffer),
transformed = new Int16Array(vertices.length * 2),
outView = new Int32Array(transformed.buffer);
for (let i = inView.length; i--;) {
outView[i*2] = outView[i*2+1] = inView[i];
}
console.log(transformed);
let vbo = gl.createBuffer();
vbo.itemCount = transformed.length;
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, transformed, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
return vbo;
}
function $(id) { return document.getElementById(id); }
function getText(id) { return $(id).innerText; }
function draw(gl, shader) {
'use strict';
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.useProgram(shader);
let attribs = [];
{
gl.bindBuffer(gl.ARRAY_BUFFER, ilaced);
let dirAttr = gl.getAttribLocation(shader, 'aDir');
if (dirAttr > -1) {
gl.enableVertexAttribArray(dirAttr);
gl.vertexAttribPointer(dirAttr, 1, gl.BYTE, false, 1, 0);
attribs.push(dirAttr);
}
}
{
gl.bindBuffer(gl.ARRAY_BUFFER, points);
let tmpPos = gl.getAttribLocation(shader, 'aPrev');
if (tmpPos > -1) {
gl.enableVertexAttribArray(tmpPos);
gl.vertexAttribPointer(tmpPos, 2, gl.SHORT, false, 0, 0);
attribs.push(tmpPos);
}
tmpPos = gl.getAttribLocation(shader, 'aCurr');
if (tmpPos > -1) {
gl.enableVertexAttribArray(tmpPos);
gl.vertexAttribPointer(tmpPos, 2, gl.SHORT, false, 0, 8);
attribs.push(tmpPos);
}
tmpPos = gl.getAttribLocation(shader, 'aNext');
if (tmpPos > -1) {
gl.enableVertexAttribArray(tmpPos);
gl.vertexAttribPointer(tmpPos, 2, gl.SHORT, false, 0, 16);
attribs.push(tmpPos);
}
}
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, points.itemCount/2-6);
for (let a of attribs) {
gl.disableVertexAttribArray(a);
}
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.useProgram(null);
}
</script>
<script language="x-shader/x-vertex" id="vshader">
precision highp float;
attribute vec2 aPrev, aCurr, aNext;
attribute float aDir;
varying vec3 uva;
varying vec2 delta;
float size = 100.;
void main () {
uva.x = aDir;
vec2 prev = aPrev/32767.;
vec2 curr = aCurr/32767.;
vec2 next = aNext/32767.;
// TODO: handle edge cases
{
vec2 deltaNext = next.xy - curr.xy;
vec2 deltaPrev = curr.xy - prev.xy;
vec2 normNext = normalize(vec2(-deltaNext.y, deltaNext.x));
vec2 normPrev = normalize(vec2(-deltaPrev.y, deltaPrev.x));
vec2 average = normalize(normNext + normPrev);
delta = average / dot(average, normPrev);
}
delta = delta*aDir/size;
gl_Position = vec4(curr+delta,0.0,1.0);
}
</script>
<script language="x-shader/x-fragment" id="fshader">
precision highp float;
varying vec3 uva;
varying vec2 delta;
void main (void)
{
float color = uva.x/2.+0.5;
gl_FragColor = vec4(color, 1.-color, 0.0, 1.0);
}
</script>
</head>
<body>
<canvas id="c" width=800 height=800></canvas>
</body>
</html>