diff options
-rw-r--r-- | src/library_gl.js | 152 |
1 files changed, 151 insertions, 1 deletions
diff --git a/src/library_gl.js b/src/library_gl.js index 322711d9..c462927d 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -22,10 +22,12 @@ var LibraryGL = { 'm': [], // modelview 'p': [] // projection }, - currentMatrix: null, + 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 @@ -808,10 +810,158 @@ var LibraryGL = { } }, + 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 */; + }, + // GL emulation: provides misc. functionality not present in OpenGL ES 2.0 or WebGL $GLEmulation__deps: ['glCreateShader', 'glShaderSource', 'glCompileShader', 'glCreateProgram', 'glDeleteShader', 'glDeleteProgram', 'glAttachShader', 'glActiveTexture', 'glGetShaderiv', 'glGetProgramiv', 'glLinkProgram'], |