Created
February 20, 2014 07:14
-
-
Save lancejpollard/9108471 to your computer and use it in GitHub Desktop.
webgl basics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var vs = document.getElementById('vs').textContent; | |
var fs = document.getElementById('fs').textContent; | |
var canvas = document.querySelector('canvas'); | |
var ctx = canvas.getContext('experimental-webgl', { | |
alpha: false, | |
antialias: true, | |
premultipliedAlpha: false, | |
stencil: true | |
}); | |
ctx.disable(ctx.DEPTH_TEST); | |
ctx.disable(ctx.CULL_FACE); | |
ctx.viewport(0, 0, canvas.width, canvas.height); | |
ctx.bindFramebuffer(ctx.FRAMEBUFFER, null); | |
ctx.clearColor(1, 1, 1, 1); | |
ctx.clear(ctx.COLOR_BUFFER_BIT); | |
ctx.activeTexture(ctx.TEXTURE0); | |
var program = ctx.createProgram(); | |
var vertexShader = ctx.createShader(ctx.VERTEX_SHADER); | |
var fragmentShader = ctx.createShader(ctx.FRAGMENT_SHADER); | |
ctx.shaderSource(vertexShader, vs); | |
ctx.compileShader(vertexShader); | |
ctx.shaderSource(fragmentShader, fs); | |
ctx.compileShader(fragmentShader); | |
ctx.attachShader(program, vertexShader); | |
ctx.attachShader(program, fragmentShader); | |
ctx.linkProgram(program); | |
ctx.useProgram(program); | |
var vertices = [ | |
-0.5, -0.5, | |
0.5, -0.5, | |
0, 0.5 | |
]; | |
var indices = [ | |
0, 1, 2 | |
]; | |
var vertexBuffer = ctx.createBuffer(); | |
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexBuffer); | |
ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(vertices), ctx.STATIC_DRAW); | |
var indexBuffer = ctx.createBuffer(); | |
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, indexBuffer); | |
ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), ctx.STATIC_DRAW); | |
var aVertexPosition = ctx.getAttribLocation(program, 'aVertexPosition'); | |
ctx.enableVertexAttribArray(aVertexPosition); | |
ctx.vertexAttribPointer(aVertexPosition, 2, ctx.FLOAT, false, 0, 0); | |
var aColor = ctx.getAttribLocation(program, 'aColor'); | |
ctx.enableVertexAttribArray(aVertexPosition); | |
ctx.vertexAttribPointer(aVertexPosition, 2, ctx.FLOAT, false, 0, 0); | |
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexBuffer); | |
ctx.drawArrays(ctx.TRIANGLES, 0, 3); |
Example with basic shapes (triangle, square, circle):
<script>
var vs = document.getElementById('vs').textContent;
var fs = document.getElementById('fs').textContent;
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('experimental-webgl', {
alpha: false,
antialias: true,
premultipliedAlpha: false,
stencil: true
});
ctx.disable(ctx.DEPTH_TEST);
ctx.disable(ctx.CULL_FACE);
ctx.viewport(0, 0, canvas.width, canvas.height);
ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
ctx.clearColor(1, 1, 1, 1);
ctx.clear(ctx.COLOR_BUFFER_BIT);
//ctx.activeTexture(ctx.TEXTURE0);
var program = ctx.createProgram();
var vertexShader = ctx.createShader(ctx.VERTEX_SHADER);
var fragmentShader = ctx.createShader(ctx.FRAGMENT_SHADER);
ctx.shaderSource(vertexShader, vs);
ctx.compileShader(vertexShader);
ctx.shaderSource(fragmentShader, fs);
ctx.compileShader(fragmentShader);
ctx.attachShader(program, vertexShader);
ctx.attachShader(program, fragmentShader);
ctx.linkProgram(program);
ctx.useProgram(program);
var vertices = [];
var indices = [];
var r = 0.0;
var g = 0.8;
var b = 0.0;
var a = 1.0;
// triangle();
// square();
circle();
var vertexBuffer = ctx.createBuffer();
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexBuffer);
ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array(vertices), ctx.STATIC_DRAW);
var indexBuffer = ctx.createBuffer();
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, indexBuffer);
ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), ctx.STATIC_DRAW);
var aVertexPosition = ctx.getAttribLocation(program, 'aVertexPosition');
var aVertexColor = ctx.getAttribLocation(program, 'aVertexColor');
// this is key to be called:
// https://www.opengl.org/wiki/Vertex_Specification
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexBuffer);
ctx.enableVertexAttribArray(aVertexPosition);
ctx.enableVertexAttribArray(aVertexColor);
ctx.vertexAttribPointer(aVertexPosition, 2, ctx.FLOAT, false, 4 * 6, 0);
ctx.vertexAttribPointer(aVertexColor, 4, ctx.FLOAT, false, 4 * 6, 4 * 2);
var pointCount = indices.length;
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, indexBuffer);
ctx.drawElements(ctx.TRIANGLE_STRIP, pointCount, ctx.UNSIGNED_SHORT, 0);
function circle() {
var arr = [];
var index = 0;
var segments = 40; // arbitrary number of points to define circumference.
var segment = (2 * Math.PI) / segments;
var x = 0;
var y = 0;
var width = 0.5;
var height = 0.5;
// add the first index
indices.push(index);
for (var i = 0, n = segments + 1; i < n; i++) {
vertices.push(x, y, r, g, b, a);
vertices.push(
x + Math.sin(segment * i) * width,
y + Math.cos(segment * i) * height,
r, g, b, a
);
indices.push(index++, index++);
}
indices.push(index - 1);
}
function square() {
vertices = [
-0.5, -0.5, r, g, b, a,
0.5, -0.5, r, g, b, a,
-0.5, 0.5, r, g, b, a,
0.5, 0.5, r, g, b, a
];
indices = [
0, 1, 2, 3
];
}
function triangle() {
vertices = [
-0.5, -0.5, r, g, b, a,
0.5, -0.5, r, g, b, a,
-0.5, 0.5, r, g, b, a
];
indices = [
0, 1, 2
];
}
</script>
Basic animation:
<canvas width="600" height="400"></canvas>
<script id="vs" type="x-shader/x-vertex">
attribute vec4 aVertexColor;
attribute vec2 aVertexPosition;
uniform mat3 translationMatrix;
uniform vec2 projectionVector;
uniform vec2 offsetVector;
uniform float alpha;
uniform vec3 tint;
varying vec4 vColor;
void main(void) {
vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);
//v -= offsetVector.xyx;
vColor = aVertexColor;
//gl_Position = vec4(projectionVector.x - 1.0, projectionVector.y + 1.0, 0.0, 1.0);
gl_Position = vec4(aVertexPosition, 0, 1);
}
</script>
<script id="fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
<script>
var next = require('component-raf');
var vs = document.getElementById('vs').textContent;
var fs = document.getElementById('fs').textContent;
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('experimental-webgl', {
alpha: false,
antialias: true,
premultipliedAlpha: false,
stencil: true
});
ctx.disable(ctx.DEPTH_TEST);
ctx.disable(ctx.CULL_FACE);
ctx.viewport(0, 0, canvas.width, canvas.height);
ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
ctx.clearColor(1, 1, 1, 1);
ctx.clear(ctx.COLOR_BUFFER_BIT);
//ctx.activeTexture(ctx.TEXTURE0);
var program = ctx.createProgram();
var vertexShader = ctx.createShader(ctx.VERTEX_SHADER);
var fragmentShader = ctx.createShader(ctx.FRAGMENT_SHADER);
ctx.shaderSource(vertexShader, vs);
ctx.compileShader(vertexShader);
ctx.shaderSource(fragmentShader, fs);
ctx.compileShader(fragmentShader);
ctx.attachShader(program, vertexShader);
ctx.attachShader(program, fragmentShader);
ctx.linkProgram(program);
ctx.useProgram(program);
var vertices = [];
var indices = [];
var r = 0.0;
var g = 0.8;
var b = 0.0;
var a = 1.0;
// triangle();
square();
// circle();
var vertexBuffer = ctx.createBuffer();
var verticesArray = new Float32Array(vertices);
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexBuffer);
ctx.bufferData(ctx.ARRAY_BUFFER, verticesArray, ctx.DYNAMIC_DRAW);
var indexBuffer = ctx.createBuffer();
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, indexBuffer);
ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), ctx.DYNAMIC_DRAW);
var aVertexPosition = ctx.getAttribLocation(program, 'aVertexPosition');
var aVertexColor = ctx.getAttribLocation(program, 'aVertexColor');
// this is key to be called:
// https://www.opengl.org/wiki/Vertex_Specification
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexBuffer);
ctx.enableVertexAttribArray(aVertexPosition);
ctx.enableVertexAttribArray(aVertexColor);
function draw() {
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexBuffer);
ctx.vertexAttribPointer(aVertexPosition, 2, ctx.FLOAT, false, 4 * 6, 0);
ctx.vertexAttribPointer(aVertexColor, 4, ctx.FLOAT, false, 4 * 6, 4 * 2);
var pointCount = indices.length;
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, indexBuffer);
ctx.drawElements(ctx.TRIANGLE_STRIP, pointCount, ctx.UNSIGNED_SHORT, 0);
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexBuffer);
ctx.bufferSubData(ctx.ARRAY_BUFFER, 0, verticesArray);
}
animate();
function animate() {
for (var i = 0, n = verticesArray.length; i < n; i++) {
verticesArray[i] += (0.001 * i);
}
draw();
next(animate);
}
function circle() {
var arr = [];
var index = 0;
var segments = 40; // arbitrary number of points to define circumference.
var segment = (2 * Math.PI) / segments;
var x = 0;
var y = 0;
var width = 0.5;
var height = 0.5;
// add the first index
indices.push(index);
for (var i = 0, n = segments + 1; i < n; i++) {
vertices.push(x, y, r, g, b, a);
vertices.push(
x + Math.sin(segment * i) * width,
y + Math.cos(segment * i) * height,
r, g, b, a
);
indices.push(index++, index++);
}
indices.push(index - 1);
}
function square() {
vertices = [
-0.5, -0.5, r, g, b, a,
0.5, -0.5, r, g, b, a,
-0.5, 0.5, r, g, b, a,
0.5, 0.5, r, g, b, a
];
indices = [
0, 1, 2, 3
];
}
function triangle() {
vertices = [
-0.5, -0.5, r, g, b, a,
0.5, -0.5, r, g, b, a,
-0.5, 0.5, r, g, b, a
];
indices = [
0, 1, 2
];
}
</script>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is how you'd combine the colors and vertices into one large array (for optimization):