diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/library_gl.js | 213 | ||||
-rw-r--r-- | src/library_sdl.js | 4 |
2 files changed, 142 insertions, 75 deletions
diff --git a/src/library_gl.js b/src/library_gl.js index 29e9687c..d3011c69 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -967,9 +967,13 @@ var LibraryGL = { } } if (source.indexOf('gl_Color') >= 0) { - source = 'attribute vec4 a_color; \n\ - varying vec4 v_color; \n' + - source.replace(/gl_Color/g, 'a_color').replace(/gl_FrontColor/g, 'v_color'); + source = 'varying vec4 v_color; \n' + + source.replace(/gl_Color/g, 'vec4(1, 1, 1, 1)').replace(/gl_FrontColor/g, 'v_color'); // XXX gl_Color can be either an attribute, or + // from glColor, and we don't know which here. + // For now, just use white + //source = 'attribute vec4 a_color; \n\ + // varying vec4 v_color; \n' + + // source.replace(/gl_Color/g, 'a_color').replace(/gl_FrontColor/g, 'v_color'); } if (source.indexOf('gl_FogFragCoord') >= 0) { source = 'varying float v_fogCoord; \n' + @@ -1034,6 +1038,32 @@ var LibraryGL = { glUseProgram(program); } + var glDeleteProgram = _glDeleteProgram; + _glDeleteProgram = function(program) { + glDeleteProgram(program); + if (program == GL.currProgram) GL.currProgram = 0; + }; + + var glBindBuffer = _glBindBuffer; + _glBindBuffer = function(target, buffer) { + glBindBuffer(target, buffer); + if (target == Module.ctx.ARRAY_BUFFER) { + GL.currArrayBuffer = buffer; + } else if (target == Module.ctx.ELEMENT_ARRAY_BUFFER) { + GL.currElementArrayBuffer = buffer; + } + }; + + var glDeleteBuffers = _glDeleteBuffers; + _glDeleteBuffers = function(n, buffers) { + glDeleteBuffers(n, buffers); + for (var i = 0; i < n; i++) { + var buffer = {{{ makeGetValue('buffers', 'i*4', 'i32') }}}; + if (buffer == GL.currArrayBuffer) GL.currArrayBuffer = 0; + if (buffer == GL.currElementArrayBuffer) GL.currElementArrayBuffer = 0; + } + }; + var glGetFloatv = _glGetFloatv; _glGetFloatv = function(pname, params) { if (pname == 0x0BA6) { // GL_MODELVIEW_MATRIX @@ -1204,11 +1234,14 @@ var LibraryGL = { }, setRenderer: function(renderer) { - this.renderer = renderer; - if (this.renderers[renderer]) return this.renderers[renderer]; - - this.createRenderer(renderer); - return this.renderers[renderer]; + var name = renderer; + if (GL.currProgram && renderer[0] != 'U') { + name = 'UD' + GL.currProgram + '|' + renderer; // user-defined program renderer + } + this.renderer = name; + if (this.renderers[name]) return this.renderers[name]; + this.renderers[name] = this.createRenderer(renderer); + return this.renderers[name]; }, createRenderer: function(renderer) { @@ -1228,7 +1261,7 @@ var LibraryGL = { textureOffset = vertexSize; } } else { - throw 'Cannot create shader rendederer for ' + renderer + ' because of ' + which; + console.log('Warning: Ignoring renderer attribute ' + which); } vertexSize += size * 4; // XXX assuming float } @@ -1236,7 +1269,7 @@ var LibraryGL = { // TODO: verify vertexSize is equal to the stride in enabled client arrays // XXX TODO: use bufferSubData to prevent reallocation of new buffers? Or all on GPU and doesn't matter? Anyhow, use DYNAMIC as hint var useCurrProgram = !!GL.currProgram; - this.renderers[renderer] = { + var ret = { vertexSize: vertexSize, hasTexture: textureSize > 0, init: function() { @@ -1253,24 +1286,24 @@ var LibraryGL = { this.vertexShader = Module.ctx.createShader(Module.ctx.VERTEX_SHADER); var zero = positionSize == 2 ? '0, ' : ''; Module.ctx.shaderSource(this.vertexShader, 'attribute vec' + positionSize + ' a_position; \n' + - 'attribute vec2 a_texCoord; \n' + + 'attribute vec2 a_texCoord0; \n' + (textureSize ? 'varying vec2 v_texCoord; \n' : '') + 'uniform mat4 u_modelView; \n' + 'uniform mat4 u_projection; \n' + 'void main() \n' + '{ \n' + ' gl_Position = u_projection * (u_modelView * vec4(a_position, ' + zero + '1.0)); \n' + - (textureSize ? 'v_texCoord = a_texCoord; \n' : '') + + (textureSize ? 'v_texCoord = a_texCoord0; \n' : '') + '} \n'); Module.ctx.compileShader(this.vertexShader); this.fragmentShader = Module.ctx.createShader(Module.ctx.FRAGMENT_SHADER); Module.ctx.shaderSource(this.fragmentShader, 'precision mediump float; \n' + 'varying vec2 v_texCoord; \n' + - 'uniform sampler2D s_texture; \n' + + 'uniform sampler2D u_texture; \n' + 'void main() \n' + '{ \n' + - (textureSize ? 'gl_FragColor = texture2D( s_texture, v_texCoord );\n' : + (textureSize ? 'gl_FragColor = texture2D( u_texture, v_texCoord );\n' : 'gl_FragColor = vec4(0.8, 0.1, 1.0, 1.0);') + '} \n'); Module.ctx.compileShader(this.fragmentShader); @@ -1282,8 +1315,8 @@ var LibraryGL = { } this.positionLocation = Module.ctx.getAttribLocation(this.program, 'a_position'); - this.texCoordLocation = Module.ctx.getAttribLocation(this.program, 'a_texCoord'); - this.textureLocation = Module.ctx.getUniformLocation(this.program, 's_texture'); + this.texCoordLocation = Module.ctx.getAttribLocation(this.program, 'a_texCoord0'); + this.textureLocation = Module.ctx.getUniformLocation(this.program, 'u_texture'); this.modelViewLocation = Module.ctx.getUniformLocation(this.program, 'u_modelView'); this.projectionLocation = Module.ctx.getUniformLocation(this.program, 'u_projection'); }, @@ -1301,16 +1334,19 @@ var LibraryGL = { } Module.ctx.enableVertexAttribArray(this.positionLocation); - var texture = Module.ctx.getParameter(Module.ctx.TEXTURE_BINDING_2D); - Module.ctx.activeTexture(Module.ctx.TEXTURE0); - Module.ctx.bindTexture(Module.ctx.TEXTURE_2D, texture); - Module.ctx.uniform1i(this.textureLocation, 0); + if (!useCurrProgram) { // otherwise, the user program will set the sampler2D binding and uniform itself + var texture = Module.ctx.getParameter(Module.ctx.TEXTURE_BINDING_2D); + Module.ctx.activeTexture(Module.ctx.TEXTURE0); + Module.ctx.bindTexture(Module.ctx.TEXTURE_2D, texture); + Module.ctx.uniform1i(this.textureLocation, 0); + } Module.ctx.uniformMatrix4fv(this.modelViewLocation, false, GL.immediate.matrix['m']); Module.ctx.uniformMatrix4fv(this.projectionLocation, false, GL.immediate.matrix['p']); } }; - this.renderers[renderer].init(); + ret.init(); + return ret; }, // Main functions @@ -1332,43 +1368,62 @@ var LibraryGL = { Module.ctx.drawArrays(mode, first, count); return; } -#if ASSERTIONS assert(first == 0); // TODO -#endif - // Client attributes are to be used here, emulate that - var stride = 0, bytes = 0, attributes = [], start, renderer = ''; - for (var i = 0; i < GL.immediate.NUM_ATTRIBUTES; i++) { - if (GL.immediate.enabledClientAttributes[i]) attributes.push(GL.immediate.clientAttributes[i]); + + var renderer = GL.immediate.prepareClientAttributes(count); + GL.immediate.mode = mode; + GL.immediate.setRenderer(renderer); + GL.immediate.flush(); + }; + + _glDrawElements = function(mode, count, type, indices) { + if (GL.immediate.totalEnabledClientAttributes == 0) { + Module.ctx.drawElements(mode, count, type, indices); + return; } - attributes.sort(function(x, y) { return !x ? (!y ? 0 : 1) : (!y ? -1 : (x.pointer - y.pointer)) }); - start = attributes[0].pointer; - for (var i = 0; i < attributes.length; i++) { - var attribute = attributes[i]; - if (!attribute) break; + + var renderer = GL.immediate.prepareClientAttributes(count); + GL.immediate.mode = mode; + GL.immediate.setRenderer(renderer); + GL.immediate.flush(count); + }; + }, + + prepareClientAttributes: function(count) { + // Client attributes are to be used here, emulate that + var stride = 0, bytes = 0, attributes = [], start, renderer = ''; + for (var i = 0; i < GL.immediate.NUM_ATTRIBUTES; i++) { + if (GL.immediate.enabledClientAttributes[i]) attributes.push(GL.immediate.clientAttributes[i]); + } + attributes.sort(function(x, y) { return !x ? (!y ? 0 : 1) : (!y ? -1 : (x.pointer - y.pointer)) }); + start = attributes[0].pointer; + for (var i = 0; i < attributes.length; i++) { + var attribute = attributes[i]; + if (!attribute) break; #if ASSERTIONS - assert(attribute.stride); - assert(stride == 0 || stride == attribute.stride); // must all be in the same buffer + assert(attribute.stride); + assert(stride == 0 || stride == attribute.stride); // must all be in the same buffer #endif - stride = attribute.stride; - bytes += attribute.size * 4 * count; // XXX assuming float - renderer += attribute.name; - } - for (var i = 0; i < attributes.length; i++) { - var attribute = attributes[i]; - if (!attribute) break; - attribute.offset = attribute.pointer - start; + stride = attribute.stride; + bytes += attribute.size * 4 * count; // XXX assuming float + renderer += attribute.name; + } + for (var i = 0; i < attributes.length; i++) { + var attribute = attributes[i]; + if (!attribute) break; + attribute.offset = attribute.pointer - start; #if ASSERTIONS - assert(0 <= attribute.offset && attribute.offset < stride); // must all be in the same buffer + assert(0 <= attribute.offset && attribute.offset < stride); // must all be in the same buffer #endif - } - GL.immediate.vertexData = {{{ makeHEAPView('F32', 'start', 'start + bytes') }}}; // XXX assuming float - GL.immediate.vertexCounter = bytes / 4; // XXX assuming float - GL.immediate.mode = mode; - GL.immediate.setRenderer(renderer); - GL.immediate.flush(); - }; + } + + GL.immediate.vertexData = {{{ makeHEAPView('F32', 'start', 'start + bytes') }}}; // XXX assuming float + GL.immediate.vertexCounter = bytes / 4; // XXX assuming float + + return renderer; }, - flush: function() { + + flush: function(numProvidedIndexes) { var renderer = this.setRenderer(this.renderer); // Generate index data in a format suitable for GLES 2.0/WebGL @@ -1377,7 +1432,9 @@ var LibraryGL = { assert(numVertexes % 1 == 0); var numIndexes = 0; - if (GL.immediate.mode > 6) { // above GL_TRIANGLE_FAN are the non-GL ES modes + if (numProvidedIndexes) { + numIndexes = numProvidedIndexes; + } else if (GL.immediate.mode > 6) { // above GL_TRIANGLE_FAN are the non-GL ES modes if (GL.immediate.mode == 7) { // GL_QUADS var numQuads = numVertexes / 4; assert(numQuads % 1 == 0); @@ -1399,22 +1456,34 @@ var LibraryGL = { Module.ctx.bufferData(Module.ctx.ELEMENT_ARRAY_BUFFER, this.indexData.subarray(0, numIndexes), Module.ctx.STATIC_DRAW); } - Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, this.vertexObject); - Module.ctx.bufferData(Module.ctx.ARRAY_BUFFER, this.vertexData.subarray(0, this.vertexCounter), Module.ctx.STATIC_DRAW); + if (!GL.currArrayBuffer) { + Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, this.vertexObject); + Module.ctx.bufferData(Module.ctx.ARRAY_BUFFER, this.vertexData.subarray(0, this.vertexCounter), Module.ctx.STATIC_DRAW); + } // Render - Module.ctx.useProgram(renderer.program); - Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, this.vertexObject); + if (!GL.currProgram) { + Module.ctx.useProgram(renderer.program); + } renderer.prepare(); if (numIndexes) { - Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, this.indexObject); + if (!numProvidedIndexes) { + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, this.indexObject); + } Module.ctx.drawElements(Module.ctx.TRIANGLES, numIndexes, Module.ctx.UNSIGNED_SHORT, 0); } else { Module.ctx.drawArrays(GL.immediate.mode, 0, numVertexes); } + if (!GL.currArrayBuffer) { + Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, null); + } + if (!GL.currProgram) { + Module.ctx.useProgram(null); + } + this.vertexCounter = 0; } }, @@ -1518,22 +1587,22 @@ var LibraryGL = { _glEnableClientState(cap, 1); }, - glTexCoordPointer: function(size, type, stride, pointer) { - GL.immediate.setClientAttribute('T' + GL.immediate.clientActiveTexture, size, type, stride, pointer); - }, glVertexPointer__deps: ['$GLEmulation'], // if any pointers are used, glVertexPointer must be, and if it is, then we need emulation glVertexPointer: function(size, type, stride, pointer) { GL.immediate.setClientAttribute('V', size, type, stride, pointer); }, - glNormalPointer: function(size, type, stride, pointer) { - GL.immediate.setClientAttribute('N', size, type, stride, pointer); + glTexCoordPointer: function(size, type, stride, pointer) { + GL.immediate.setClientAttribute('T' + GL.immediate.clientActiveTexture, size, type, stride, pointer); + }, + glNormalPointer: function(type, stride, pointer) { + GL.immediate.setClientAttribute('N', 1, type, stride, pointer); }, glColorPointer: function(size, type, stride, pointer) { GL.immediate.setClientAttribute('C', size, type, stride, pointer); }, glClientActiveTexture: function(texture) { - GL.immediate.clientActiveTexture = texture; + GL.immediate.clientActiveTexture = texture - 0x84C0; // GL_TEXTURE0 }, // OpenGL Immediate Mode matrix routines. @@ -1566,27 +1635,23 @@ var LibraryGL = { }, glLoadMatrixd: function(matrix) { - GL.immediate.matrix.lib.mat4.set(GL.immediate.matrix[GL.immediate.currentMatrix], - {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}); + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]); }, glLoadMatrixf: function(matrix) { #if GL_DEBUG console.log('glLoadMatrixf receiving: ' + Array.prototype.slice.call(HEAPF32.subarray(matrix >> 2, (matrix >> 2) + 16))); #endif - GL.immediate.matrix.lib.mat4.set(GL.immediate.matrix[GL.immediate.currentMatrix], - {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}); + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]); }, glLoadTransposeMatrixd: function(matrix) { - GL.immediate.matrix.lib.mat4.set(GL.immediate.matrix[GL.immediate.currentMatrix], - {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}); + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]); GL.immediate.matrix.lib.mat4.transpose(GL.immediate.matrix[GL.immediate.currentMatrix]); }, glLoadTransposeMatrixf: function(matrix) { - GL.immediate.matrix.lib.mat4.set(GL.immediate.matrix[GL.immediate.currentMatrix], - {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}); + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]); GL.immediate.matrix.lib.mat4.transpose(GL.immediate.matrix[GL.immediate.currentMatrix]); }, @@ -1602,16 +1667,14 @@ var LibraryGL = { glMultTransposeMatrixd: function(matrix) { var colMajor = GL.immediate.matrix.lib.mat4.create(); - GL.immediate.matrix.lib.mat4.set(colMajor, - {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}); + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}, colMajor); GL.immediate.matrix.lib.mat4.transpose(colMajor); GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], colMajor); }, glMultTransposeMatrixf: function(matrix) { var colMajor = GL.immediate.matrix.lib.mat4.create(); - GL.immediate.matrix.lib.mat4.set(colMajor, - {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}); + GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}, colMajor); GL.immediate.matrix.lib.mat4.transpose(colMajor); GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], colMajor); }, diff --git a/src/library_sdl.js b/src/library_sdl.js index 9e9bf10f..a4923352 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -774,6 +774,10 @@ var LibrarySDL = { // SDL_Image + IMG_Init: function(flags) { + return flags; // We support JPG, PNG, TIF because browsers do + }, + IMG_Load__deps: ['SDL_LockSurface'], IMG_Load: function(filename) { filename = FS.standardizePath(Pointer_stringify(filename)); |