diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/library_gl.js | 189 |
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 |