Skip to content

Commit

Permalink
WebGL 3D with projection and model-view matrices.
Browse files Browse the repository at this point in the history
  • Loading branch information
david-geo-holmes committed Apr 24, 2013
1 parent c8f0133 commit 66aae08
Show file tree
Hide file tree
Showing 3 changed files with 280 additions and 1 deletion.
1 change: 0 additions & 1 deletion example/webgl/webgl-0004-movement.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ <h1>WebGL Movement</h1>
gl.clearColor(0.1, 0.5, 0.1, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0, 0, 400, 300);
global angle;
translation = sin(elapsed * 2.0 * 3.14159 / 10000.0)/2.0;
triangleVertices = [-0.5 + translation, 0.5, 0.0,
0.0 + translation, 0.0, 0.0,
Expand Down
146 changes: 146 additions & 0 deletions example/webgl/webgl-0005-3d.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL 3D</title>

<style type="text/css">
body { background-color: grey;}
canvas { background-color: white;}
</style>

<script src="../../dist/skulpt.js" type="text/javascript"></script>
<script src="../../dist/builtin.js" type="text/javascript"></script>
</head>

<body>
<h1>WebGL 3D</h1>
<form>
<textarea id="code" name="code" cols="120" rows="40">
import webgl
from math import sin

gl = webgl.Context("my-canvas")
trianglesVerticeBuffer = gl.createBuffer()
trianglesColorBuffer = gl.createBuffer()
program = None
uViewMatrix = None
uProjMatrix = None
viewMatrix = webgl.Matrix4x4([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0])
projMatrix = webgl.Matrix4x4([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0])

def setup():
print viewMatrix
print projMatrix
global program, uViewMatrix, uProjMatrix
vs = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vs, "" +
"attribute vec3 aVertexPosition;" +
"attribute vec3 aVertexColor;" +
"" +
"uniform mat4 uViewMatrix;" +
"uniform mat4 uProjMatrix;" +
"" +
"varying highp vec4 vColor;" +
"void main(void) {" +
" gl_Position = uProjMatrix * uViewMatrix * vec4(aVertexPosition, 1.0);" +
" vColor = vec4(aVertexColor, 1.0);" +
"}")
gl.compileShader(vs)
print "Vertex shader COMPILE_STATUS: " + str(gl.getShaderParameter(vs, gl.COMPILE_STATUS))
fs = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fs, "" +
"varying highp vec4 vColor;" +
"void main(void) {" +
" gl_FragColor = vColor;" +
"}")
gl.compileShader(fs)
print "Fragment shader COMPILE_STATUS: " + str(gl.getShaderParameter(fs, gl.COMPILE_STATUS))

program = gl.createProgram()
gl.attachShader(program, vs)
gl.attachShader(program, fs)
gl.linkProgram(program)
print "Program LINK_STATUS: " + str(gl.getProgramParameter(program, gl.LINK_STATUS))
gl.useProgram(program)

triangleVerticeColors = [1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0]

gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer)
gl.bufferData(gl.ARRAY_BUFFER, webgl.Float32Array(triangleVerticeColors), gl.STATIC_DRAW)

uViewMatrix = gl.getUniformLocation(program, "uViewMatrix")
uProjMatrix = gl.getUniformLocation(program, "uProjMatrix")
projMatrix.perspective(45, 4.0/3.0, 0.1, 100.0)
viewMatrix.identity()
viewMatrix.translate([0.0, 0.0, -2.0])
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.viewport(0, 0, 400, 300);

def draw(gl, elapsed):
gl.clear(gl.COLOR_BUFFER_BIT);
translation = sin(elapsed * 2.0 * 3.14159 / 10000.0)/2.0;
triangleVertices = [-0.5 + translation, 0.5, -0.5,
0.0 + translation, 0.0, -0.5,
-0.5 + translation, -0.5, -0.5,
0.5 + translation, 0.5, 0.5,
0.0 + translation, 0.0, 0.5,
0.5 + translation, -0.5, 0.5]
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer)
gl.bufferData(gl.ARRAY_BUFFER, webgl.Float32Array(triangleVertices), gl.DYNAMIC_DRAW)

gl.uniformMatrix4fv(uProjMatrix, False, projMatrix)
gl.uniformMatrix4fv(uViewMatrix, False, viewMatrix)

vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition")
gl.enableVertexAttribArray(vertexPositionAttribute)
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer)
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, False, 0, 0)

vertexColorAttribute = gl.getAttribLocation(program, "aVertexColor")
gl.enableVertexAttribArray(vertexColorAttribute)
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer)
gl.vertexAttribPointer(vertexColorAttribute, 3, gl.FLOAT, False, 0, 0)

gl.drawArrays(gl.TRIANGLES, 0, 6)

setup()

gl.setDrawFunc(draw);
</textarea>
<button onclick="runit()" type="button">Run</button>
</form>
<canvas id="my-canvas" height="300" width="400">
Your browser does not support the HTML5 canvas element.
</canvas>
<pre id="my-output" ></pre>
<script>
function outputHandler(text) {
var output = document.getElementById("my-output");
output.innerHTML = output.innerHTML + text.replace(/</g, '&lt;');
}

function builtinRead(x) {
if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined) {
throw "File not found: '" + x + "'";
}
return Sk.builtinFiles["files"][x];
}

function runit() {
var prog = document.getElementById("code").value;
// Clear the output
document.getElementById("my-output").innerHTML = '';
Sk.canvas = "my-canvas";
Sk.pre = "my-output";
Sk.configure({"output":outputHandler, "read":builtinRead});
try {
eval(Sk.importMainWithBody("<stdin>", false, prog));
}
catch(e) {
alert(e);
}
}
</script>
</body>
</html>
134 changes: 134 additions & 0 deletions src/lib/webgl/__init__.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,15 @@ var $builtinmodule = function(name)
case 'getAttribLocation': {
}
break;
case 'getUniformLocation': {
}
break;
case 'shaderSource': {
}
break;
case 'uniformMatrix4fv': {
}
break;
case 'vertexAttribPointer': {
}
break;
Expand Down Expand Up @@ -167,6 +173,12 @@ var $builtinmodule = function(name)
}
);

$loc.getUniformLocation = new Sk.builtin.func(
function(self, program, name) {
return self.gl.getUniformLocation(program, name.v);
}
);

$loc.shaderSource = new Sk.builtin.func(
function(self, shader, src) {
self.gl.shaderSource(shader, src.v);
Expand All @@ -191,6 +203,15 @@ var $builtinmodule = function(name)
}
);

$loc.uniformMatrix4fv = new Sk.builtin.func(
function(self, location, transpose, values) {
// console.log("location " + (typeof location));
// console.log("transpose " + (typeof transpose));
// console.log("values.v " + (typeof values.v));
self.gl.uniformMatrix4fv(Sk.builtin.asnum$(location), transpose, values.v);
}
);

$loc.setDrawFunc = new Sk.builtin.func(function(self, func) {
var startTime = (new Date()).getTime();
var intervalId = setInterval(
Expand Down Expand Up @@ -220,5 +241,118 @@ var $builtinmodule = function(name)
});
}, 'Float32Array', []);

/**
* A 4x4 (mutable) matrix suitable for OpenGL.
*
* Mutability is chosen for performance.
* The inderlying implementation is Float32Array.
* The indexing of the elements is
* 0 4 8 12
* 1 5 9 13
* 2 6 10 14
* 3 7 11 15
*/
mod.Matrix4x4 = Sk.misceval.buildClass(mod, function($gbl, $loc) {
$loc.__init__ = new Sk.builtin.func(function(self, data) {
self.v = new Float32Array(Sk.ffi.remapToJs(data));
});

$loc.identity = new Sk.builtin.func(
function(self) {

var m = self.v;

m[0] = 1;
m[1] = 0;
m[2] = 0;
m[3] = 0;

m[4] = 0;
m[5] = 1;
m[6] = 0;
m[7] = 0;

m[8] = 0;
m[9] = 0;
m[10] = 1;
m[11] = 0;

m[12] = 0;
m[13] = 0;
m[14] = 0;
m[15] = 1;
}
);

$loc.perspective = new Sk.builtin.func(
function(self, fov, aspect, near, far) {

var t = Math.tan(Math.PI * 0.5 - 0.5 * (Sk.builtin.asnum$(fov) * Math.PI / 180));
var a = Sk.builtin.asnum$(aspect)
var n = Sk.builtin.asnum$(near)
var f = Sk.builtin.asnum$(far)
var k = 1.0 / (n - f);

var m = self.v;

m[0] = t / a;
m[1] = 0;
m[2] = 0;
m[3] = 0;

m[4] = 0;
m[5] = t;
m[6] = 0;
m[7] = 0;

m[8] = 0;
m[9] = 0;
m[10] = (n + f) * k;
m[11] = -1;

m[12] = 0;
m[13] = 0;
m[14] = n * f * k * 2;
m[15] = 0;
}
);

$loc.translate = new Sk.builtin.func(
function(self, translation) {

var m = self.v;
var t = Sk.ffi.remapToJs(translation);

m[0] = 1;
m[1] = 0;
m[2] = 0;
m[3] = 0;

m[4] = 0;
m[5] = 1;
m[6] = 0;
m[7] = 0;

m[8] = 0;
m[9] = 0;
m[10] = 1;
m[11] = 0;

m[12] = t[0];
m[13] = t[1];
m[14] = t[2];
m[15] = 1;
}
);

$loc.__repr__ = new Sk.builtin.func(function(self) {
var copy = [];
for (var i = 0; i < self.v.length; ++i) {
copy.push(self.v[i]);
}
return new Sk.builtin.str("[" + copy.join(', ') + "]");
});
}, 'Matrix4x4', []);

return mod;
};

0 comments on commit 66aae08

Please sign in to comment.