aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/library_gl.js189
1 files changed, 182 insertions, 7 deletions
diff --git a/src/library_gl.js b/src/library_gl.js
index f5652ff9..f5235a3f 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -14,7 +14,22 @@ var LibraryGL = {
uniforms: {},
shaders: {},
- matrix: {},
+ // The folowing data structures are used for OpenGL Immediate Mode matrix routines.
+ matrix: {
+ 'm': null, // modelview
+ 'p': null // projection
+ },
+ matrixStack: {
+ 'm': [], // modelview
+ 'p': [] // projection
+ },
+ currentMatrix: 'm', // default is modelview
+ tempMatrix: null,
+ initMatrixLibrary: function() {
+ GL.matrix['m'] = GL.matrix.lib.mat4.create();
+ GL.matrix['p'] = GL.matrix.lib.mat4.create();
+ GL.tempMatrix = GL.matrix.lib.mat4.create();
+ },
// Linear lookup in one of the tables (buffers, programs, etc.). TODO: consider using a weakmap to make this faster, if it matters
scan: function(table, object) {
@@ -788,6 +803,170 @@ var LibraryGL = {
return Module.ctx.isFramebuffer(fb);
},
+ // OpenGL Immediate Mode matrix routines.
+ // Note that in the future we might make these available only in certain modes.
+ glMatrixMode: function(mode) {
+ if (mode == 0x1700 /* GL_MODELVIEW */) {
+ GL.currentMatrix = 'm';
+ } else if (mode == 0x1701 /* GL_PROJECTION */) {
+ GL.currentMatrix = 'p';
+ } else {
+ throw "Wrong mode " + mode + " passed to glMatrixMode";
+ }
+ },
+
+ glPushMatrix: function() {
+ GL.matrixStack[GL.currentMatrix].push(
+ Array.prototype.slice.call(GL.matrix[GL.currentMatrix]));
+ },
+
+ glPopMatrix: function() {
+ GL.matrix[currentMatrix] = GL.matrixStack[GL.currentMatrix].pop();
+ },
+
+ glLoadIdentity: function() {
+ GL.matrix.lib.mat4.identity(GL.matrix[GL.currentMatrix]);
+ },
+
+ glLoadMatrixd: function(matrix) {
+ GL.matrix.lib.mat4.set(GL.matrix[GL.currentMatrix],
+ {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}});
+ },
+
+ glLoadMatrixf: function(matrix) {
+ GL.matrix.lib.mat4.set(GL.matrix[GL.currentMatrix],
+ {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}});
+ },
+
+ glLoadTransposeMatrixd: function(matrix) {
+ GL.matrix.lib.mat4.set(GL.matrix[GL.currentMatrix],
+ {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}});
+ GL.matrix.lib.mat4.transpose(GL.matrix[GL.currentMatrix]);
+ },
+
+ glLoadTransposeMatrixf: function(matrix) {
+ GL.matrix.lib.mat4.set(GL.matrix[GL.currentMatrix],
+ {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}});
+ GL.matrix.lib.mat4.transpose(GL.matrix[GL.currentMatrix]);
+ },
+
+ glMultMatrixd: function(matrix) {
+ GL.matrix.lib.mat4.multiply(GL.matrix[GL.currentMatrix],
+ {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}});
+ },
+
+ glMultMatrixf: function(matrix) {
+ GL.matrix.lib.mat4.multiply(GL.matrix[GL.currentMatrix],
+ {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}});
+ },
+
+ glMultTransposeMatrixd: function(matrix) {
+ var colMajor = GL.matrix.lib.mat4.create();
+ GL.matrix.lib.mat4.set(colMajor,
+ {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}});
+ GL.matrix.lib.mat4.transpose(colMajor);
+ GL.matrix.lib.mat4.multiply(GL.matrix[GL.currentMatrix], colMajor);
+ },
+
+ glMultTransposeMatrixf: function(matrix) {
+ var colMajor = GL.matrix.lib.mat4.create();
+ GL.matrix.lib.mat4.set(colMajor,
+ {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}});
+ GL.matrix.lib.mat4.transpose(colMajor);
+ GL.matrix.lib.mat4.multiply(GL.matrix[GL.currentMatrix], colMajor);
+ },
+
+ gluPerspective: function(fov, aspect, near, far) {
+ GL.matrix.lib.mat4.multiply(GL.matrix[GL.currentMatrix],
+ GL.matrix.lib.mat4.perspective(fov, aspect, near, far, GL.tempMatrix));
+ },
+
+ glFrustum: function(left, right, bottom, top_, nearVal, farVal) {
+ GL.matrix.lib.mat4.multiply(GL.matrix[GL.currentMatrix],
+ GL.matrix.lib.mat4.frustum(left, right, bottom, top_, nearVal, farVal));
+ },
+
+ glOrtho: function(left, right, bottom, top_, nearVal, farVal) {
+ GL.matrix.lib.mat4.multiply(GL.matrix[GL.currentMatrix],
+ GL.matrix.lib.mat4.ortho(left, right, bottom, top_, nearVal, farVal));
+ },
+
+ glScaled: function(x, y, z) {
+ GL.matrix.lib.mat4.scale(GL.matrix[GL.currentMatrix], [x, y, z]);
+ },
+
+ glScalef: function(x, y, z) {
+ _glScalef(x, y, z);
+ },
+
+ glTranslate: function(x, y, z) {
+ GL.matrix.lib.mat4.translate(GL.matrix[GL.currentMatrix], [x, y, z]);
+ },
+
+ glTranslatef: function(x, y, z) {
+ _glTranslated(x, y, z);
+ },
+
+ glRotated: function(angle, x, y, z) {
+ GL.matrix.lib.mat4.rotate(GL.matrix[GL.currentMatrix], angle, [x, y, z]);
+ },
+
+ glRotatef: function(angle, x, y, z) {
+ _glRotated(angle, x, y, z);
+ },
+
+ gluLookAt: function(ex, ey, ez, cx, cy, cz, ux, uy, uz) {
+ GL.matrix.lib.mat4.lookAt(GL.matrix[GL.currentMatrix], [ex, ey, ez],
+ [cx, cy, cz], [ux, uy, uz]);
+ },
+
+ gluProject: function(objX, objY, objZ, model, proj, view, winX, winY, winZ) {
+ // The algorithm for this functions comes from Mesa
+
+ var inVec = new Float32Array(4);
+ var outVec = new Float32Array(4);
+ GL.matrix.lib.mat4.multiplyVec4({{{ makeHEAPView('F64', 'model', 'model+16*8') }}},
+ [objX, objY, objZ, 1.0], outVec);
+ GL.matrix.lib.mat4.multiplyVec4({{{ makeHEAPView('F64', 'proj', 'proj+16*8') }}},
+ outVec, inVec);
+ if (inVec[3] == 0.0) {
+ return 0 /* GL_FALSE */;
+ }
+ inVec[0] /= inVec[3];
+ inVec[1] /= inVec[3];
+ inVec[2] /= inVec[3];
+ // Map x, y and z to range 0-1 */
+ inVec[0] = inVec[0] * 0.5 + 0.5;
+ inVec[1] = inVec[1] * 0.5 + 0.5;
+ inVec[2] = inVec[2] * 0.5 + 0.5;
+ // Map x, y to viewport
+ inVec[0] = inVec[0] * {{{ makeGetValue('view', '2*4', 'i32') }}} + {{{ makeGetValue('view', '0*4', 'i32') }}};
+ inVec[1] = inVec[1] * {{{ makeGetValue('view', '3*4', 'i32') }}} + {{{ makeGetValue('view', '1*4', 'i32') }}};
+
+ {{{ makeSetValue('winX', '0', 'inVec[0]', 'double') }}};
+ {{{ makeSetValue('winY', '0', 'inVec[1]', 'double') }}};
+ {{{ makeSetValue('winZ', '0', 'inVec[2]', 'double') }}};
+
+ return 1 /* GL_TRUE */;
+ },
+
+ gluUnProject: function(winX, winY, winZ, model, proj, view, objX, objY, objZ) {
+ var result = GL.matrix.lib.mat4.unproject([winX, winY, winZ],
+ {{{ makeHEAPView('F64', 'model', 'model+16*8') }}},
+ {{{ makeHEAPView('F64', 'proj', 'proj+16*8') }}},
+ {{{ makeHEAPView('32', 'view', 'view+4*4') }}});
+
+ if (result === null) {
+ return 0 /* GL_FALSE */;
+ }
+
+ {{{ makeSetValue('objX', '0', 'result[0]', 'double') }}};
+ {{{ makeSetValue('objY', '0', 'result[1]', 'double') }}};
+ {{{ makeSetValue('objZ', '0', 'result[2]', 'double') }}};
+
+ return 1 /* GL_TRUE */;
+ },
+
glEnable: function(cap) {
if (cap == 0x0DE1) return; // no GL_TEXTURE_2D in GLES or WebGL
Module.ctx.enable(cap);
@@ -931,7 +1110,8 @@ var LibraryGL = {
}
},
- glBegin__deps: ['$GL', '$GLImmediate', function() { return 'GL.matrix.lib = ' + read('gl-matrix.js') + ';\nGL.immediate = GLImmediate;\n' }],
+ glBegin__deps: ['$GL', '$GLImmediate', function() { return 'GL.matrix.lib = ' + read('gl-matrix.js') +
+ ';\nGL.immediate = GLImmediate;\nGL.initMatrixLibrary();\n' }],
glBegin: function(mode) {
if (!GL.immediate.initted) GL.immediate.init();
GL.immediate.mode = mode;
@@ -972,11 +1152,6 @@ var LibraryGL = {
GL.immediate.vertexData[5*GL.immediate.vertexCounter+3] = u;
GL.immediate.vertexData[5*GL.immediate.vertexCounter+4] = v;
},
-
- // TODO
- glMatrixMode: function(){},
- glLoadIdentity: function(){},
- glOrtho: function(){},
};
// Simple pass-through functions. Starred ones have return values. [X] ones have X in the C name but not in the JS name