<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width" />
<title>WebGL thing</title>
<style type="text/css">
* {
margin: 0; padding: 0; border: 0;
background: #000 url("/images/lithium-wallpaper.png") center / cover;
}
canvas { display: block; width: 100%; background: none }
</style>
</head>
<body><canvas width="320"></canvas></body>
<script id="fragment" type="x-shader/fragment">
precision mediump float;
varying vec3 Color;
/* texture mapping happens here */
void main () {
// gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
gl_FragColor = vec4(Color, 1);
}
</script><script id="vertex" type="x-shader/vertex">
attribute vec3 vertex;
attribute vec3 color;
varying vec3 Color;
uniform vec3 rotation;
uniform mat4 projection, view, translation;
/* coordinate transformations happen here */
void main () {
Color = color;
//gl_PointSize = 1.1;
mat4 rotate_x = mat4(0.0);
rotate_x[0][0] = 1.0;
rotate_x[1][1] = cos(rotation.x);
rotate_x[1][2] = -sin(rotation.x);
rotate_x[2][1] = sin(rotation.x);
rotate_x[2][2] = cos(rotation.x);
rotate_x[3][3] = 1.0;
mat4 rotate_y = mat4(0.0);
rotate_y[0][0] = cos(rotation.y);
rotate_y[1][1] = 1.0;
rotate_y[2][0] = sin(rotation.y);
rotate_y[0][2] = -sin(rotation.y);
rotate_y[2][2] = cos(rotation.y);
rotate_y[3][3] = 1.0;
mat4 rotate_z = mat4(0.0);
rotate_z[0][0] = cos(rotation.z);
rotate_z[1][0] = -sin(rotation.z);
rotate_z[0][1] = sin(rotation.z);
rotate_z[1][1] = cos(rotation.z);
rotate_z[2][2] = 1.0;
rotate_z[3][3] = 1.0;
mat4 model = translation * rotate_x * rotate_y * rotate_z;
gl_Position = projection * view * model * vec4(vertex, 1.0);
}
</script><script type="text/javascript">
var canvas = document.getElementsByTagName("canvas")[0];
var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
if (!gl) {
alert("sorry, you need webgl for this.");
//history.back();
}
function compile_shader (type, id) {
var shader = gl.createShader(type);
gl.shaderSource(shader, document.getElementById(id).innerHTML);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
console.log(gl.getShaderInfoLog(shader));
return shader;
}
var shader = gl.createProgram();
gl.attachShader(shader, compile_shader(gl.FRAGMENT_SHADER, "fragment"));
gl.attachShader(shader, compile_shader(gl.VERTEX_SHADER, "vertex"));
gl.linkProgram(shader);
if (!gl.getProgramParameter(shader, gl.LINK_STATUS))
console.log(gl.getProgramInfoLog(shader));
gl.useProgram(shader);
var cube = {
vertices: { data: [
1, 1,-1,-1, 1,-1, 1,-1,-1,-1,-1,-1,-1,-1,
1,-1, 1,-1,-1, 1, 1, 1, 1,-1, 1, 1, 1, 1,
-1,-1, 1,-1, 1,-1,-1, 1, 1, 1, 1,-1, 1, 1
] }, colors: { data: [
1,1,1,0,1,1,1,0,1,0,0,1,0,0,
0,0,1,1,0,1,0,1,1,1,1,1,0,1,
0,1,1,0,0,0,0,0,1,1,0,0,1,0
] }
};
function load_uniform (pgm, dst, src) {
src.vbo = gl.createBuffer(1);
gl.bindBuffer(gl.ARRAY_BUFFER, src.vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(src.data), gl.STATIC_DRAW);
var uniform = gl.getAttribLocation(shader, dst);
gl.enableVertexAttribArray(uniform);
gl.vertexAttribPointer(uniform, 3, gl.FLOAT, gl.FALSE, 0, 0);
return uniform;
}
load_uniform(shader, "vertex", cube.vertices);
load_uniform(shader, "color", cube.colors);
var matrix = {
identity: function () {
return new Float32Array([ 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1 ]);
}
};
matrix.projection = {
data: matrix.identity(),
uniform: gl.getUniformLocation(shader, "projection")
};
matrix.projection.data[ 5] = 2;
matrix.projection.data[11] = 0.75; // perspective
matrix.view = {
data: matrix.identity(),
uniform: gl.getUniformLocation(shader, "view")
};
// model matrix = rotate * translate * scale
matrix.translation = {
data: matrix.identity(),
uniform: gl.getUniformLocation(shader, "translation")
};
matrix.translation.data[15] = 4;
onresize = function () {
gl.viewport(0, 0, innerWidth, innerHeight);
canvas.height = innerHeight;
canvas.width = innerWidth;
matrix.projection.data[0] = 2 * canvas.height / canvas.width;
gl.uniformMatrix4fv(
matrix.projection.uniform, false,
matrix.projection.data
);
refresh();
}
onresize();
gl.uniformMatrix4fv(matrix.view.uniform, false, matrix.view.data);
gl.uniformMatrix4fv(matrix.translation.uniform, false, matrix.translation.data);
/*
var texture = gl.createTexture(1);
gl.bindTexture(gl.TEXTURE_2D, texture);
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
*/
gl.enable(gl.DEPTH_TEST);
/*
gl.depthFunc(gl.LESS);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.BLEND);
gl.lineWidth(2);
*/
function push_vector3f (pgm, dest, one, two, three) {
gl.uniform3f(
gl.getUniformLocation(pgm, dest),
one, two, three
);
}
function refresh () {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 14);
}
var i = 0;
var speed = 20;
function doFrame () {
i = ++i < 360 * speed ? i : 0;
var theta = Math.PI * i / 180 / speed;
push_vector3f(shader, "rotation", 3 * theta, 5 * theta, 7 * theta);
refresh();
}
var frame_interval;// = setInterval(doFrame, 1000 / 60);
doFrame();
document.onclick = function () {
if (frame_interval) frame_interval = clearInterval(frame_interval);
else {
var el = document.documentElement,
rfs = el.requestFullScreen
|| el.webkitRequestFullScreen
|| el.mozRequestFullScreen;
rfs.call(el);
frame_interval = setInterval(doFrame, 1000 / 60);
}
console.log("frame interval: " + frame_interval);
}
</script></body>
</html>