Skip to content

Commit 1dfb03e

Browse files
author
Evan Wallace
committed
added documentation
1 parent 921fb98 commit 1dfb03e

9 files changed

+436
-92
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.DS_Store
22
*.pyc
3+
docs
34
lightgl.js

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This library makes it easier to quickly prototype WebGL applications. It's lower
77
* `python build.py`: build `lightgl.js` from the files in the `src` directory
88
* `python build.py debug`: rebuild the library any time the contents of the `src` directory change
99
* `python build.py release`: minify the library using Google Closure Compiler, which assumes there is a `closure` command in your path that runs `compiler.jar`
10+
* `docco src/*.js`: build the documentation, which is generated in the `docs` directory
1011

1112
## Sample code
1213

src/main.js

+113-25
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,56 @@
1+
// The API for this library is modeled off of [Processing](http://processing.org) and only
2+
// supports a single WebGL canvas for simplicity. The global WebGL context is stored in
3+
// `gl`, which is augmented with additional functions for matrix manipulation.
4+
//
5+
// Example usage:
6+
//
7+
// <script src="lightgl.js"></script>
8+
// <script>
9+
//
10+
// var time = 0;
11+
//
12+
// function setup() {
13+
// document.body.appendChild(gl.canvas);
14+
// }
15+
//
16+
// function update(seconds) {
17+
// time += seconds;
18+
// }
19+
//
20+
// function draw() {
21+
// gl.clearColor(1, Math.cos(time), Math.sin(time), 1);
22+
// gl.clear(gl.COLOR_BUFFER_BIT);
23+
// }
24+
//
25+
// </script>
26+
27+
// ### Error Handling
28+
//
29+
// To handle errors, like WebGL initialization errors or shader compile errors,
30+
// just provide a custom implementation of the `fail()` function.
31+
function fail(text) {
32+
if (window.fail) window.fail(text);
33+
else throw text;
34+
}
35+
36+
// ### Initialization
37+
// When the page is loaded, a WebGL canvas singleton is automatically created. The default
38+
// resolution is 800x600, which can be changed by setting `gl.canvas.width` and `gl.canvas.height`
39+
// and then calling `gl.viewport()`.
140
window.onload = function() {
2-
// Set up WebGL
341
var canvas = document.createElement('canvas');
442
canvas.width = 800;
543
canvas.height = 600;
644
window.gl = null;
745
try { gl = canvas.getContext('webgl'); } catch (e) {}
846
try { gl = gl || canvas.getContext('experimental-webgl'); } catch (e) {}
9-
if (!gl) throw 'WebGL not supported';
47+
if (!gl) { fail('WebGL not supported'); return; }
1048

11-
// Add custom enums
49+
// Provide an implementation of the OpenGL matrix stack (only modelview
50+
// and projection matrices), as well as some useful GLU matrix functions.
1251
var ENUM = 0x12340000;
1352
gl.MODELVIEW = ENUM | 1;
1453
gl.PROJECTION = ENUM | 2;
15-
16-
// Add matrix funcitons
1754
gl.modelviewMatrix = new Matrix();
1855
gl.projectionMatrix = new Matrix();
1956
var modelviewStack = [];
@@ -70,50 +107,101 @@ window.onload = function() {
70107
gl.matrixMode(gl.MODELVIEW);
71108
gl.autoDraw = true;
72109

73-
// Set up the animation loop
110+
// Set up the animation loop. If your application doesn't need continuous
111+
// redrawing, set `gl.autoDraw = false` in your `setup()` function.
74112
var post =
75113
window.webkitRequestAnimationFrame ||
76114
window.mozRequestAnimationFrame ||
77115
function(callback) { setTimeout(callback, 1000 / 60); };
78116
var time;
79117
function frame() {
80-
var now = new Date();
81-
if (window.update) window.update((now - (time || now)) / 1000);
82-
time = now;
83-
if (window.draw) window.draw();
84-
if (gl.autoDraw) post(frame);
118+
try {
119+
var now = new Date();
120+
if (window.update) window.update((now - (time || now)) / 1000);
121+
time = now;
122+
if (window.draw) window.draw();
123+
if (gl.autoDraw) post(frame);
124+
} catch (text) {
125+
fail(text);
126+
}
85127
}
86128

87-
// Draw the initial frame and start the animation loop
88-
if (window.setup) window.setup();
89-
frame();
129+
// Draw the initial frame and start the animation loop.
130+
try {
131+
if (window.setup) window.setup();
132+
frame();
133+
} catch (text) {
134+
fail(text);
135+
}
90136
};
91137

92-
var isDragging = false;
138+
// ### Mouse Input
139+
//
140+
// The interface for mouse input is also taken from Processing. Mouse state
141+
// can be accessed through the `mouseX`, `mouseY`, `deltaMouseX`, `deltaMouseY`,
142+
// and `mouseDragging` global variables. Example usage:
143+
//
144+
// function mousePressed() {
145+
// // Called when any mouse button is pressed
146+
// }
147+
//
148+
// function mouseDragged() {
149+
// // Called when the mouse moves while pressed
150+
// }
151+
//
152+
// function mouseMoved() {
153+
// // Called when the mouse moves while released
154+
// }
155+
//
156+
// function mouseReleased() {
157+
// // Called when any mouse button is released
158+
// }
159+
160+
mouseX = mouseY = deltaMouseX = deltaMouseY = 0;
161+
mouseDragging = false;
162+
163+
var oldMouseX = 0;
164+
var oldMouseY = 0;
93165

94166
function setMouseInfo(e) {
95-
window.mouseX = e.pageX;
96-
window.mouseY = e.pageY;
167+
mouseX = e.pageX;
168+
mouseY = e.pageY;
97169
for (var obj = gl.canvas; obj; obj = obj.offsetParent) {
98-
window.mouseX -= obj.offsetLeft;
99-
window.mouseY -= obj.offsetTop;
170+
mouseX -= obj.offsetLeft;
171+
mouseY -= obj.offsetTop;
100172
}
173+
deltaMouseX = mouseX - oldMouseX;
174+
deltaMouseY = mouseY - oldMouseY;
175+
oldMouseX = mouseX;
176+
oldMouseY = mouseY;
101177
}
102178

103179
document.onmousedown = function(e) {
104180
setMouseInfo(e);
105-
isDragging = true;
106-
if (window.mousePressed) window.mousePressed();
181+
mouseDragging = true;
182+
try {
183+
if (window.mousePressed) window.mousePressed();
184+
} catch (text) {
185+
fail(text);
186+
}
107187
};
108188

109189
document.onmousemove = function(e) {
110190
setMouseInfo(e);
111-
if (!isDragging && window.mouseMoved) window.mouseMoved();
112-
else if (isDragging && window.mouseDragged) window.mouseDragged();
191+
try {
192+
if (!mouseDragging && window.mouseMoved) window.mouseMoved();
193+
else if (mouseDragging && window.mouseDragged) window.mouseDragged();
194+
} catch (text) {
195+
fail(text);
196+
}
113197
};
114198

115199
document.onmouseup = function(e) {
116200
setMouseInfo(e);
117-
isDragging = false;
118-
if (window.mouseReleased) window.mouseReleased();
201+
mouseDragging = false;
202+
try {
203+
if (window.mouseReleased) window.mouseReleased();
204+
} catch (text) {
205+
fail(text);
206+
}
119207
};

src/matrix.js

+55-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// Represents a 4x4 matrix.
2+
3+
// ### new Matrix([elements])
4+
//
5+
// This constructor takes 16 arguments, which can be passed individually, as
6+
// a list, or even as four lists, one for each row. If the arguments are
7+
// omitted then the identity matrix is constructed instead.
18
Matrix = function() {
29
this.m = Array.prototype.concat.apply([], arguments);
310
if (!this.m.length) {
@@ -10,8 +17,12 @@ Matrix = function() {
1017
}
1118
};
1219

20+
// ### .inverse()
21+
//
22+
// Returns the matrix that when multiplied with this matrix results in the
23+
// identity matrix. This implementation is from the Mesa OpenGL function
24+
// `__gluInvertMatrixd()` found in `project.c`.
1325
Matrix.prototype.inverse = function() {
14-
// Implementation from the Mesa OpenGL function __gluInvertMatrixd()
1526
var m = this.m, inv = new Matrix(
1627
m[5]*m[10]*m[15] - m[5]*m[14]*m[11] - m[6]*m[9]*m[15] + m[6]*m[13]*m[11] + m[7]*m[9]*m[14] - m[7]*m[13]*m[10],
1728
-m[1]*m[10]*m[15] + m[1]*m[14]*m[11] + m[2]*m[9]*m[15] - m[2]*m[13]*m[11] - m[3]*m[9]*m[14] + m[3]*m[13]*m[10],
@@ -39,6 +50,10 @@ Matrix.prototype.inverse = function() {
3950
return inv;
4051
};
4152

53+
// ### .multiply(matrix)
54+
//
55+
// Concatenates the transforms for this matrix and `matrix`.
56+
// This emulates the OpenGL function `glMultMatrix()`.
4257
Matrix.prototype.multiply = function(matrix) {
4358
var a = this.m, b = matrix.m;
4459
return new Matrix(
@@ -64,6 +79,10 @@ Matrix.prototype.multiply = function(matrix) {
6479
);
6580
};
6681

82+
// ### .transformPoint(point)
83+
//
84+
// Transforms the vector as a point with a `w` coordinate of `1`. This
85+
// means translations will have an effect, for example.
6786
Matrix.prototype.transformPoint = function(v) {
6887
var m = this.m;
6988
return new Vector(
@@ -73,6 +92,10 @@ Matrix.prototype.transformPoint = function(v) {
7392
).divide(m[12] * v.x + m[13] * v.y + m[14] * v.z + m[15]);
7493
};
7594

95+
// ### .transformPoint(vector)
96+
//
97+
// Transforms the vector as a vector with a `w` coordinate of `0`. This
98+
// means translations will have no effect, for example.
7699
Matrix.prototype.transformVector = function(v) {
77100
var m = this.m;
78101
return new Vector(
@@ -82,12 +105,23 @@ Matrix.prototype.transformVector = function(v) {
82105
);
83106
};
84107

108+
// ### .perspective(fov, aspect, near, far)
109+
//
110+
// Sets up a perspective transform, which makes far away objects appear smaller
111+
// than nearby objects. The `aspect` argument is the width divided by the height
112+
// of your viewport and `fov` is the top-to-bottom angle of the field of view in
113+
// degrees. This emulates the OpenGL function `gluPerspective()`.
85114
Matrix.perspective = function(fov, aspect, near, far) {
86115
var y = Math.tan(fov * Math.PI / 360) * near;
87116
var x = y * aspect;
88117
return Matrix.frustum(-x, x, -y, y, near, far);
89118
};
90119

120+
// ### .frustum(left, right, bottom, top, near, far)
121+
//
122+
// Sets up a viewing frustum, which is shaped like a truncated pyramid with the
123+
// camera where the point of the pyramid would be. This emulates the OpenGL
124+
// function `glFrustum()`.
91125
Matrix.frustum = function(l, r, b, t, n, f) {
92126
return new Matrix(
93127
2*n/(r-l), 0, (r+l)/(r-l), 0,
@@ -97,6 +131,11 @@ Matrix.frustum = function(l, r, b, t, n, f) {
97131
);
98132
};
99133

134+
// ### .ortho(left, right, bottom, top, near, far)
135+
//
136+
// Creates an orthographic projection, in which objects are the same size no
137+
// matter how far away or nearby they are. This emulates the OpenGL function
138+
// `glOrtho()`.
100139
Matrix.ortho = function(l, r, b, t, n, f) {
101140
return new Matrix(
102141
2/(r-l), 0, 0, (r+l)/(r-l),
@@ -106,6 +145,9 @@ Matrix.ortho = function(l, r, b, t, n, f) {
106145
);
107146
};
108147

148+
// ### .scale(x, y, z)
149+
//
150+
// This emulates the OpenGL function `glScale()`.
109151
Matrix.scale = function(x, y, z) {
110152
return new Matrix(
111153
x, 0, 0, 0,
@@ -115,6 +157,9 @@ Matrix.scale = function(x, y, z) {
115157
);
116158
};
117159

160+
// ### .translate(x, y, z)
161+
//
162+
// This emulates the OpenGL function `glTranslate()`.
118163
Matrix.translate = function(x, y, z) {
119164
return new Matrix(
120165
1, 0, 0, x,
@@ -124,6 +169,10 @@ Matrix.translate = function(x, y, z) {
124169
);
125170
};
126171

172+
// ### .rotate(a, x, y, z)
173+
//
174+
// Creates a matrix that rotates by `a` degrees around the vector `x, y, z`.
175+
// This emulates the OpenGL function `glRotate()`.
127176
Matrix.rotate = function(a, x, y, z) {
128177
if (a && (x || y || z)) {
129178
var d = Math.sqrt(x*x + y*y + z*z);
@@ -140,6 +189,11 @@ Matrix.rotate = function(a, x, y, z) {
140189
}
141190
};
142191

192+
// ### .lookAt(ex, ey, ez, cx, cy, cz, ux, uy, uz)
193+
//
194+
// Create a matrix that puts the camera at the eye point `ex, ey, ez` looking
195+
// toward the center point `cx, cy, cz` with an up direction of `ux, uy, uz`.
196+
// This emulates the OpenGL function `gluLookAt()`.
143197
Matrix.lookAt = function(ex, ey, ez, cx, cy, cz, ux, uy, uz) {
144198
var e = new Vector(ex, ey, ez);
145199
var c = new Vector(cx, cy, cz);

0 commit comments

Comments
 (0)