aboutsummaryrefslogtreecommitdiff
path: root/src/library_gl.js
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-05-08 15:39:04 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-05-08 15:39:04 -0700
commitce088b42f999c0d36553960a1bca09eb273e0833 (patch)
tree0d13276dd9aa786b5658da68dda1cf3a5bc5fbfd /src/library_gl.js
parent7344940ec4bf2d3032a5309c52d7fa0e2c35692d (diff)
begin refactoring client attribute emulation to allow arbitrary typed elements. breaks glBegin/end
Diffstat (limited to 'src/library_gl.js')
-rw-r--r--src/library_gl.js138
1 files changed, 58 insertions, 80 deletions
diff --git a/src/library_gl.js b/src/library_gl.js
index 78355046..6df229c0 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -1227,9 +1227,8 @@ var LibraryGL = {
vertexCounter: 0,
mode: 0,
- renderers: {},
- renderer: null,
- rendererComponents: {},
+ rendererCache: {},
+ rendererComponents: {}, // cache for calls inside glBegin/end, XXX not yet implemented
// The following data structures are used for OpenGL Immediate Mode matrix routines.
matrix: {},
@@ -1249,11 +1248,13 @@ var LibraryGL = {
TEXTURE5: 8,
TEXTURE6: 9,
NUM_ATTRIBUTES: 10,
+ NUM_TEXTURES: 7,
ATTRIBUTE_BY_NAME: {},
totalEnabledClientAttributes: 0,
enabledClientAttributes: [0, 0],
- clientAttributes: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
+ clientAttributes: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}], // raw data, including possible unneeded ones
+ liveClientAttributes: [], // the ones actually alive in the current computation, sorted
clientActiveTexture: 0,
clientColor: null,
@@ -1269,79 +1270,65 @@ var LibraryGL = {
setClientAttribute: function(name, size, type, stride, pointer) {
var attrib = this.clientAttributes[GL.immediate.ATTRIBUTE_BY_NAME[name]];
+ attrib.name = name;
attrib.size = size;
attrib.type = type;
attrib.stride = stride;
attrib.pointer = pointer;
- attrib.name = name + size;
},
// Renderers
- addRendererComponent: function(component) {
+ addRendererComponent: function(component) { // XXX needs rewriting
if (this.rendererComponents[component]) return;
this.rendererComponents[component] = 1;
- this.renderer += component;
},
- setRenderer: function(renderer) {
- var name = renderer;
- if (GL.currProgram && renderer[0] != 'U') {
- name = 'UD' + GL.currProgram + '|' + renderer; // user-defined program renderer
+ getRenderer: function() {
+ // return a renderer object given the liveClientAttributes
+ // we maintain a cache of renderers, optimized to not generate garbage
+ var attributes = GL.immediate.liveClientAttributes;
+ var cacheItem = GL.immediate.rendererCache;
+ for (var i = 0; i < attributes.length; i++) {
+ var attribute = attributes[i];
+ if (!cacheItem[attribute.name]) cacheItem[attribute.name] = {};
+ cacheItem = cacheItem[attribute.name];
+ if (!cacheItem[attribute.size]) cacheItem[attribute.size] = {};
+ cacheItem = cacheItem[attribute.size];
+ if (!cacheItem[attribute.type]) cacheItem[attribute.type] = {};
+ cacheItem = cacheItem[attribute.type];
+ }
+ if (GL.currProgram) {
+ if (!cacheItem[GL.currProgram]) cacheItem[GL.currProgram] = {};
+ cacheItem = cacheItem[GL.currProgram];
}
- this.renderer = name;
- if (this.renderers[name]) return this.renderers[name];
- this.renderers[name] = this.createRenderer(renderer);
- return this.renderers[name];
+ if (!cacheItem.renderer) {
+#if GL_DEBUG
+ console.log('generating renderer for ' + JSON.stringify(attributes));
+#endif
+ cacheItem.renderer = this.createRenderer();
+ }
+ return cacheItem.renderer;
},
createRenderer: function(renderer) {
- var vertexSize = 0, positionSize = 0, positionOffset = 0, colorSize = 0, colorOffset = 0, normalSize = 0, normalOffset = 0;
- var textureSizes = [], textureOffsets = [], textureTypes = [], hasTextures = false;
- var which, size, index;
- for (var i = 0; i < renderer.length; i+=2) {
- var which = renderer[i];
- if (which == 'V') {
- size = parseInt(renderer[i+1]);
- positionSize = size;
- positionOffset = vertexSize;
- vertexSize += size * 4; // XXX assuming float
- } else if (which == 'T') {
- index = parseInt(renderer[i+1])
- size = parseInt(renderer[i+2]);
- i++;
- textureSizes[index] = size;
- textureOffsets[index] = vertexSize;
- if (renderer[i+2] == 's') { // special case: half-size texture
- i++;
- vertexSize += size * 2;
- textureTypes[index] = Module.ctx.SHORT;
- } else {
- vertexSize += size * 4;
- textureTypes[index] = Module.ctx.FLOAT;
- }
+ var useCurrProgram = !!GL.currProgram;
+ var hasTextures = false, textureSizes = [], textureTypes = [], textureOffsets = [];
+ for (var i = 0; i < GL.immediate.NUM_TEXTURES; i++) {
+ if (GL.immediate.enabledClientAttributes[GL.immediate.TEXTURE0 + i]) {
+ textureSizes[i] = GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + i].size;
+ textureTypes[i] = GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + i].type;
+ textureOffsets[i] = GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + i].offset;
hasTextures = true;
- } else if (which == 'N') {
- size = parseInt(renderer[i+1]);
- normalSize = size;
- normalOffset = vertexSize;
- vertexSize += 4; // 3 chars, + alignment
- } else if (which == 'C') {
- size = parseInt(renderer[i+1]);
- colorSize = size;
- colorOffset = vertexSize;
- vertexSize += 4; // Up to 4 chars, + alignment
- } else {
- console.log('Warning: Ignoring renderer attribute ' + which);
- size = parseInt(renderer[i+1]);
- vertexSize += size * 4; // XXX assuming float
}
}
- assert(positionSize > 0);
- // TODO: verify vertexSize is equal to the stride in enabled client arrays
- var useCurrProgram = !!GL.currProgram;
+ var stride = GL.immediate.stride;
+ var positionSize = GL.immediate.clientAttributes[GL.immediate.VERTEX].size;
+ var positionOffset = GL.immediate.clientAttributes[GL.immediate.VERTEX].offset;
+ var colorSize = GL.immediate.clientAttributes[GL.immediate.COLOR].size;
+ var colorOffset = GL.immediate.clientAttributes[GL.immediate.COLOR].offset;
+ var normalSize = GL.immediate.clientAttributes[GL.immediate.NORMAL].size;
+ var normalOffset = GL.immediate.clientAttributes[GL.immediate.NORMAL].offset;
var ret = {
- vertexSize: vertexSize,
-
init: function() {
if (useCurrProgram) {
if (GL.shaderInfos[GL.programShaders[GL.currProgram][0]].type == Module.ctx.VERTEX_SHADER) {
@@ -1417,20 +1404,20 @@ var LibraryGL = {
if (this.projectionLocation) Module.ctx.uniformMatrix4fv(this.projectionLocation, false, GL.immediate.matrix['p']);
Module.ctx.vertexAttribPointer(this.positionLocation, positionSize, Module.ctx.FLOAT, false,
- vertexSize, positionOffset);
+ stride, positionOffset);
Module.ctx.enableVertexAttribArray(this.positionLocation);
if (this.hasTextures) {
for (var i = 0; i < textureSizes.length; i++) {
if (textureSizes[i] && this.texCoordLocations[i] >= 0) {
Module.ctx.vertexAttribPointer(this.texCoordLocations[i], textureSizes[i], textureTypes[i], false,
- vertexSize, textureOffsets[i]);
+ stride, textureOffsets[i]);
Module.ctx.enableVertexAttribArray(this.texCoordLocations[i]);
}
}
}
if (this.hasColorAttrib) {
Module.ctx.vertexAttribPointer(this.colorLocation, colorSize, Module.ctx.UNSIGNED_BYTE, true,
- vertexSize, colorOffset);
+ stride, colorOffset);
Module.ctx.enableVertexAttribArray(this.colorLocation);
Module.ctx.uniform1i(this.hasColorAttribLocation, 1);
} else if (this.hasColorUniform) {
@@ -1439,7 +1426,7 @@ var LibraryGL = {
}
if (this.hasNormal) {
Module.ctx.vertexAttribPointer(this.normalLocation, normalSize, Module.ctx.BYTE, true,
- vertexSize, normalOffset);
+ stride, normalOffset);
Module.ctx.enableVertexAttribArray(this.normalLocation);
}
if (!useCurrProgram) { // otherwise, the user program will set the sampler2D binding and uniform itself
@@ -1528,7 +1515,7 @@ var LibraryGL = {
Module.ctx.drawArrays(mode, first, count);
return;
}
- GL.immediate.renderer = GL.immediate.prepareClientAttributes(count);
+ GL.immediate.prepareClientAttributes(count);
GL.immediate.mode = mode;
GL.immediate.flush(null, first);
};
@@ -1538,17 +1525,16 @@ var LibraryGL = {
Module.ctx.drawElements(mode, count, type, indices);
return;
}
- GL.immediate.renderer = GL.immediate.prepareClientAttributes(count);
+ GL.immediate.prepareClientAttributes(count);
GL.immediate.mode = mode;
GL.immediate.flush(count, indices);
};
},
- tempClientAttributes: [],
prepareClientAttributes: function(count) {
// Client attributes are to be used here, emulate that
var stride = 0, start;
- var attributes = GL.immediate.tempClientAttributes;
+ var attributes = GL.immediate.liveClientAttributes;
attributes.length = 0;
for (var i = 0; i < GL.immediate.NUM_ATTRIBUTES; i++) {
if (GL.immediate.enabledClientAttributes[i]) attributes.push(GL.immediate.clientAttributes[i]);
@@ -1565,51 +1551,42 @@ var LibraryGL = {
stride = attribute.stride;
}
- var renderer = '', bytes = 0;
+ var bytes = 0;
for (var i = 0; i < attributes.length; i++) {
var attribute = attributes[i];
if (!attribute) break;
attribute.offset = attribute.pointer - start;
if (attribute.offset > bytes) { // ensure we start where we should
assert((attribute.offset - bytes)%4 == 0); // XXX assuming 4-alignment
- renderer += '?' + ((attribute.offset - bytes)/4);
bytes += attribute.offset - bytes;
}
- renderer += attribute.name;
bytes += attribute.size * GL.immediate.byteSizeByType[attribute.type];
- if (attribute.name[0] == 'T' && GL.immediate.byteSizeByType[attribute.type] == 2) {
- renderer += 's'; // special case, texture coords can be 4 *or* 2-size
- }
if (bytes % 4 != 0) bytes += 4 - (bytes % 4); // XXX assuming 4-alignment
#if ASSERTIONS
assert(0 <= attribute.offset && attribute.offset < stride); // must all be in the same buffer
#endif
}
-
assert(stride == 0 || bytes <= stride);
-
if (bytes < stride) { // ensure the size is that of the stride
assert((stride - bytes)%4 == 0); // assuming float
- renderer += '?' + ((stride-bytes)/4);
bytes = stride;
}
+ GL.immediate.stride = bytes;
bytes *= count;
if (!GL.currArrayBuffer) {
GL.immediate.vertexData = {{{ makeHEAPView('F32', 'start', 'start + bytes') }}}; // XXX assuming float
}
GL.immediate.vertexCounter = bytes / 4; // XXX assuming float
-
- return renderer;
},
flush: function(numProvidedIndexes, startIndex) {
startIndex = startIndex || 0;
- var renderer = this.setRenderer(this.renderer);
+ var renderer = this.getRenderer();
// Generate index data in a format suitable for GLES 2.0/WebGL
- var numVertexes = 4 * this.vertexCounter / renderer.vertexSize; // XXX assuming float
+ var numVertexes = 4 * this.vertexCounter / GL.immediate.stride; // XXX assuming float
assert(numVertexes % 1 == 0);
var numIndexes = 0;
@@ -1678,12 +1655,13 @@ var LibraryGL = {
glBegin__deps: ['$GLImmediateSetup'],
glBegin: function(mode) {
GL.immediate.mode = mode;
- GL.immediate.renderer = '';
GL.immediate.rendererComponents = {}; // XXX
GL.immediate.vertexData = GL.immediate.tempData;
},
glEnd: function() {
+ GL.immediate.prepareClientAttributes();
+ GL.immediate.mode = mode;
GL.immediate.flush();
},