Skip to content

Instantly share code, notes, and snippets.

@frondeus
Created April 1, 2016 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frondeus/8d921960a5082cb53e0369ad4fdd4b9d to your computer and use it in GitHub Desktop.
Save frondeus/8d921960a5082cb53e0369ad4fdd4b9d to your computer and use it in GitHub Desktop.
Renderer 3D.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Render 3D</title>
</head>
<body>
<script src="canvasquery.js" type="text/javascript" charset="utf-8"></script>
<script src="main.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
(function() {
var layer = cq(800, 600).appendTo(document.body);
layer.strokeStyle("#fff");
var cube = {
vertices: [
[-1, -1, -1], //0
[1, -1, -1], //1
[-1, 1, -1], //2
[1, 1, -1], //3
[-1, -1, 1], //4
[1, -1, 1], //5
[-1, 1, 1], //6
[1, 1, 1] // 8
],
indices: [
1, 0, 3, // back
3, 0, 2,
4, 5, 6, // front
6, 5, 7,
5, 1, 7, //left
7, 1, 3,
0, 4, 2, //right
2, 4, 6,
0, 1, 4, //top
4, 1, 5,
6, 7, 2, //bottom
2, 7, 3
]
};
var Matrix = function(mat, width, height) {
this.mat = mat;
this.width = width;
this.height = height;
};
/* e f
* g h
* a b a*e + b*g a*f + b*h
* c d c*e + d*g c*f + d*h
*
* */
Matrix.prototype = {
mul: function(other) {
var out = [];
for(var i = 0; i < this.width * other.height; i++) out.push(0);
for(var x = 0; x < this.width; x++) {
for(var y = 0; y < other.height; y++) {
var sum = 0;
var outI = y + other.height * x;
for(var z = 0; z < other.width; z++) {
var mI = z + this.width * x;
var oI = y + other.height * z;
sum += this.mat[mI] * other.mat[oI];
}
out[outI] = sum;
}
}
return new Matrix(out, this.width, other.height);
}
};
var toVec4 = function(vec3) {
return new Matrix([ vec3[0], vec3[1], vec3[2], 1.0], 4, 1);
};
var bound = function(x, min, max) {
return Math.max(min, Math.min(max, Math.round(x)));
};
var toViewPort = function(vec4, width, height) {
var x = vec4.mat[0];
var y = vec4.mat[1];
var z = vec4.mat[2];
x /= z;
y /= z;
x = width * ( x + 1.0) / 2.0;
y = height * (1.0 - (( y + 1.0 ) /2.0));
return {
x: bound(x, 0, width),
y: bound(y, 0, height)
};
};
var Ortho = function(left, right, top, bottom, near, far) {
return new Matrix([
2 / (right - left), 0 , 0, -(right + left)/(right - left),
0, 2 / (top - bottom), 0, -(top + bottom) / (top - bottom),
0, 0, -2 / (far - near), -(far + near) / (far - near),
0, 0, 0, 1
], 4, 4);
};
var RotateY = function(angle) {
return new Matrix([
Math.cos(angle), 0, Math.sin(angle), 0,
0, 1, 0, 0,
-Math.sin(angle), 0, Math.cos(angle), 0,
0, 0, 0, 1
], 4, 4);
};
var Translate = function(x, y, z) {
return new Matrix([
1, 0, 0, x,
0, 1, 0, y,
0, 0, 1, z,
0, 0, 0, 1
], 4, 4);
}
var ang = 0;
var render = function() {
layer.clear("#333");
var pos = [];
var proj = Ortho(-8, 8, 6, -6, 0.01, 100.0);
var rotate = RotateY(ang);
var translate = Translate(2, 0, 0);
var model = translate.mul(rotate);
//var model = rotate.mul(translate);
ang += 0.01;
//ModelViewProj. MVP.
var modelProj = proj.mul(model);
for(var i in cube.vertices) {
// Vertex shader.
pos[i] = toVec4(cube.vertices[i]);
pos[i] = modelProj.mul(pos[i]);
// Po Vertex shaderze.
pos[i] = toViewPort(pos[i], 800, 600);
}
for(var i = 0, len = cube.indices.length; i < len; i++) {
var i1 = cube.indices[i++];
var i2 = cube.indices[i++];
var i3 = cube.indices[i];
var v1 = pos[i1];
var v2 = pos[i2];
var v3 = pos[i3];
layer
.strokeLine(v1.x, v1.y, v2.x, v2.y)
.strokeLine(v2.x, v2.y, v3.x, v3.y)
.strokeLine(v1.x, v1.y, v3.x, v3.y);
}
};
setInterval(function() {
render();
}, 1000 / 60);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment