aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/library_gl.js213
-rw-r--r--src/library_sdl.js4
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));