Нет описания

trixl.html 6.1KB

    <!doctype html> <html> <head> <title>.trixl</title> <meta charset="utf-8" /> <style> #stage { position: absolute; top: 0; left: 0; } #debug { position: absolute; bottom: 0; right: 0; } </style> </head> <body> <canvas id="stage"> sorry. your browser is from the dark ages. please initiate temporal leap to a minimally brighter future where browsers can investigate the third dimension. </canvas> <span id="debug"></span> <script type="gl/vertex-shader"> attribute vec3 pos; varying vec3 world_pos; uniform mat4 transform; void main() { world_pos = pos; gl_Position = vec4(transform * vec4(pos, 1)); } </script> <script type="gl/fragment-shader"> precision mediump float; uniform vec4 color; varying vec3 world_pos; void main() { if (color.x >= 0.0 && color.x <= 1.0) { gl_FragColor = color; } else { gl_FragColor = vec4(world_pos.x, world_pos.y, world_pos.z, 1); } } </script> <script src="gl.js"></script> <script src="geometry.js"></script> <script src="matrix.js"></script> <script src="glmatrix.js"></script> <script> mat4.multiplyMany = function() { var m = arguments[0]; for(var i = 1; i < arguments.length; i++) { m = mat4.multiply([], arguments[i], m); } return m; } </script> <script> window.trixl = {}; trixl.stage = document.querySelector("#stage"); trixl.window = {w: window.innerWidth, h: window.innerHeight}; trixl.stage.width = trixl.window.w; trixl.stage.height = trixl.window.h; trixl.debug = document.querySelector("#debug"); trixl.debug_pos = function(pos) { var coord_html = function(coord) { var s = (coord.toString() + " ").slice(0, 6); if (coord < -1.0 || coord > 1.0) { return '<span style="color: red">' + s + '</span>'; } else { return '<span>' + s + '</span>'; } return s; } return coord_html(pos[0]) + ", " + coord_html(pos[1]) + ", " + coord_html(pos[2]); } var gl = trixl.gl = trixl.stage.getContext("webgl"); //gl.enable(gl.CULL_FACE); gl.enable(gl.DEPTH_TEST); var vertexPosBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(geometry.cube()), gl.STATIC_DRAW); var vs = document.querySelector("script[type='gl/vertex-shader']").textContent; var fs = document.querySelector("script[type='gl/fragment-shader']").textContent; var program = createProgram(vs, fs); gl.useProgram(program); program.vertexPosAttrib = gl.getAttribLocation(program, 'pos'); gl.enableVertexAttribArray(program.vertexPosAttrib); gl.vertexAttribPointer(program.vertexPosBuffer, 3, gl.FLOAT, false, 0, 0); program.color = gl.getUniformLocation(program, 'color'); gl.uniform4f(program.color, -1, -1, -1, -1); trixl.pos = {x: 0, y: 0, z: 0, a: 0}; var angle = {x: 0, y: 0, z: 0}; var offset = {x: 0, y: 0, z: 0}; program.transform = gl.getUniformLocation(program, 'transform'); trixl.redraw = function() { var camera = mat4.multiplyMany( matrix.translate(trixl.pos.x, trixl.pos.y, trixl.pos.z), matrix.rotateY(trixl.pos.a) ); var camera_pos = [camera[12], camera[13], camera[14]]; var up = [0, 1, 0]; camera = mat4.lookAt([], camera_pos, [0, 0, 0], up); var view = mat4.invert([], camera); var aspect = trixl.window.w / trixl.window.h; var transform = function(pos) { return mat4.multiplyMany( //matrix.scale(0.6, 0.6, 0.6), matrix.translate(-0.5, -0.5, -0.5), matrix.rotateZ(angle.z / 10), //matrix.rotateY(angle.y / 10), matrix.rotateX(angle.x / 10), matrix.translate(pos[0] + offset.x, pos[1] + offset.y, pos[2] + offset.z), view, matrix.persective(Math.PI / 3, aspect) ); } var t = transform([0.0, 0.0, 2]); trixl.debug.innerHTML = ""; [[0, 0, 0], [0, 1, 0], [1, 0, 0], [1, 1, 0], [0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1]].forEach(function(el) { trixl.debug.innerHTML += trixl.debug_pos(matrix.multiply([el[0], el[1], el[2], 1], [1, 4], t, [4, 4])); trixl.debug.innerHTML += "<br />"; }); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.uniform4f(program.color, (Math.sin(angle.x) + 1.0) * 0.5, 0, 0, 1.0); gl.uniformMatrix4fv(program.transform, false, t); gl.drawArrays(gl.TRIANGLES, 0, 6 * 6); var c = (Math.sin(angle.x) + 1.0) * 0.5; gl.uniform4f(program.color, c, c, c, 1.0); gl.uniformMatrix4fv(program.transform, false, transform([-3.0, 0.0, 2])); gl.drawArrays(gl.TRIANGLES, 0, 6 * 6); gl.uniformMatrix4fv(program.transform, false, transform([+3.0, 0.0, 2])); gl.drawArrays(gl.TRIANGLES, 0, 6 * 6); gl.uniformMatrix4fv(program.transform, false, transform([+0.0, +3.0, 2])); gl.drawArrays(gl.TRIANGLES, 0, 6 * 6); gl.uniformMatrix4fv(program.transform, false, transform([+0.0, -3.0, 2])); gl.drawArrays(gl.TRIANGLES, 0, 6 * 6); gl.uniform4f(program.color, -1, -1, -1, 0); angle.x += Math.PI / 10; angle.y += Math.PI / 10; angle.z += Math.PI / 10; offset.x = Math.sin(angle.x * 0.1); offset.y = Math.sin(angle.y * 0.1); offset.z = Math.cos(angle.z * 0.1) * 2; } trixl.step = function() { trixl.redraw(); trixl.step.reqId = requestAnimationFrame(trixl.step); } trixl.start = function() { trixl.step.reqId = requestAnimationFrame(trixl.step); } trixl.stop = function() { cancelAnimationFrame(trixl.step.reqId); trixl.step.reqId = null; } trixl.start(); document.addEventListener("keydown", function(ev) { switch (ev.keyCode) { case 32: if (trixl.step.reqId == null) { trixl.start(); } else { trixl.stop(); } break; case 37: // left trixl.pos.x -= 0.1; break; case 38: // up trixl.pos.z -= 0.1; break; case 39: // right trixl.pos.x += 0.1; break; case 40: // down trixl.pos.z += 0.1; break; } }); window.onresize = function() { trixl.window.w = window.innerWidth; trixl.window.h = window.innerHeight; trixl.stage.width = trixl.window.w; trixl.stage.height = trixl.window.h; gl.viewport(0, 0, trixl.window.w, trixl.window.h); trixl.redraw(); } </script> </body> </html>