aboutsummaryrefslogtreecommitdiff
path: root/src/library_gl.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/library_gl.js')
-rw-r--r--src/library_gl.js168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/library_gl.js b/src/library_gl.js
index 16ea5531..83e68777 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -217,6 +217,23 @@ var LibraryGL = {
throw 'Invalid format (' + format + ')';
}
break;
+ case 0x1403 /* GL_UNSIGNED_SHORT */:
+ if (format == 0x1902 /* GL_DEPTH_COMPONENT */) {
+ sizePerPixel = 2;
+ } else {
+ throw 'Invalid format (' + format + ')';
+ }
+ break;
+ case 0x1405 /* GL_UNSIGNED_INT */:
+ if (format == 0x1902 /* GL_DEPTH_COMPONENT */) {
+ sizePerPixel = 4;
+ } else {
+ throw 'Invalid format (' + format + ')';
+ }
+ break;
+ case 0x84FA /* UNSIGNED_INT_24_8_WEBGL */:
+ sizePerPixel = 4;
+ break;
case 0x8363 /* GL_UNSIGNED_SHORT_5_6_5 */:
case 0x8033 /* GL_UNSIGNED_SHORT_4_4_4_4 */:
case 0x8034 /* GL_UNSIGNED_SHORT_5_5_5_1 */:
@@ -244,6 +261,8 @@ var LibraryGL = {
pixels = {{{ makeHEAPView('U8', 'pixels', 'pixels+bytes') }}};
} else if (type == 0x1406 /* GL_FLOAT */) {
pixels = {{{ makeHEAPView('F32', 'pixels', 'pixels+bytes') }}};
+ } else if (type == 0x1405 /* GL_UNSIGNED_INT */ || type == 0x84FA /* UNSIGNED_INT_24_8_WEBGL */) {
+ pixels = {{{ makeHEAPView('U32', 'pixels', 'pixels+bytes') }}};
} else {
pixels = {{{ makeHEAPView('U16', 'pixels', 'pixels+bytes') }}};
}
@@ -291,6 +310,9 @@ var LibraryGL = {
Module.ctx.bufferSubData(Module.ctx.ARRAY_BUFFER,
0,
HEAPU8.subarray(cb.ptr, cb.ptr + size));
+#if GL_ASSERTIONS
+ GL.validateVertexAttribPointer(cb.size, cb.type, cb.stride, 0);
+#endif
Module.ctx.vertexAttribPointer(i, cb.size, cb.type, cb.normalized, cb.stride, 0);
}
},
@@ -302,6 +324,56 @@ var LibraryGL = {
},
#endif
+#if GL_ASSERTIONS
+ validateGLObjectID: function(objectHandleArray, objectID, callerFunctionName, objectReadableType) {
+ if (objectID != 0) {
+ if (objectHandleArray[objectID] === null) {
+ console.error(callerFunctionName + ' called with an already deleted ' + objectReadableType + ' ID ' + objectID + '!');
+ } else if (!objectHandleArray[objectID]) {
+ console.error(callerFunctionName + ' called with an invalid ' + objectReadableType + ' ID ' + objectID + '!');
+ }
+ }
+ },
+ // Validates that user obeys GL spec #6.4: http://www.khronos.org/registry/webgl/specs/latest/1.0/#6.4
+ validateVertexAttribPointer: function(dimension, dataType, stride, offset) {
+ var sizeBytes = 1;
+ switch(dataType) {
+ case 0x1400 /* GL_BYTE */:
+ case 0x1401 /* GL_UNSIGNED_BYTE */:
+ sizeBytes = 1;
+ break;
+ case 0x1402 /* GL_SHORT */:
+ case 0x1403 /* GL_UNSIGNED_SHORT */:
+ sizeBytes = 2;
+ break;
+ case 0x1404 /* GL_INT */:
+ case 0x1405 /* GL_UNSIGNED_INT */:
+ case 0x1406 /* GL_FLOAT */:
+ sizeBytes = 4;
+ break;
+ case 0x140A /* GL_DOUBLE */:
+ sizeBytes = 8;
+ break;
+ default:
+ console.error('Invalid vertex attribute data type GLenum ' + dataType + ' passed to GL function!');
+ }
+ if (dimension == 0x80E1 /* GL_BGRA */) {
+ console.error('WebGL does not support size=GL_BGRA in a call to glVertexAttribPointer! Please use size=4 and type=GL_UNSIGNED_BYTE instead!');
+ } else if (dimension < 1 || dimension > 4) {
+ console.error('Invalid dimension='+dimension+' in call to glVertexAttribPointer, must be 1,2,3 or 4.');
+ }
+ if (stride < 0 || stride > 255) {
+ console.error('Invalid stride='+stride+' in call to glVertexAttribPointer. Note that maximum supported stride in WebGL is 255!');
+ }
+ if (offset % sizeBytes != 0) {
+ console.error('GL spec section 6.4 error: vertex attribute data offset of ' + offset + ' bytes should have been a multiple of the data type size that was used: GLenum ' + dataType + ' has size of ' + sizeBytes + ' bytes!');
+ }
+ if (stride % sizeBytes != 0) {
+ console.error('GL spec section 6.4 error: vertex attribute data stride of ' + stride + ' bytes should have been a multiple of the data type size that was used: GLenum ' + dataType + ' has size of ' + sizeBytes + ' bytes!');
+ }
+ },
+#endif
+
initExtensions: function() {
if (GL.initExtensions.done) return;
GL.initExtensions.done = true;
@@ -334,6 +406,10 @@ var LibraryGL = {
GL.elementIndexUintExt = Module.ctx.getExtension('OES_element_index_uint');
GL.standardDerivativesExt = Module.ctx.getExtension('OES_standard_derivatives');
+
+ GL.depthTextureExt = Module.ctx.getExtension("WEBGL_depth_texture") ||
+ Module.ctx.getExtension("MOZ_WEBGL_depth_texture") ||
+ Module.ctx.getExtension("WEBKIT_WEBGL_depth_texture");
}
},
@@ -588,6 +664,9 @@ var LibraryGL = {
glBindTexture__sig: 'vii',
glBindTexture: function(target, texture) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.textures, texture, 'glBindTexture', 'texture');
+#endif
Module.ctx.bindTexture(target, texture ? GL.textures[texture] : null);
},
@@ -710,6 +789,9 @@ var LibraryGL = {
glBindRenderbuffer__sig: 'vii',
glBindRenderbuffer: function(target, renderbuffer) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.renderbuffers, renderbuffer, 'glBindRenderbuffer', 'renderbuffer');
+#endif
Module.ctx.bindRenderbuffer(target, renderbuffer ? GL.renderbuffers[renderbuffer] : null);
},
@@ -727,6 +809,9 @@ var LibraryGL = {
glGetUniformfv__sig: 'viii',
glGetUniformfv: function(program, location, params) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glGetUniformfv', 'program');
+#endif
var data = Module.ctx.getUniform(GL.programs[program], GL.uniforms[location]);
if (typeof data == 'number') {
{{{ makeSetValue('params', '0', 'data', 'float') }}};
@@ -739,6 +824,9 @@ var LibraryGL = {
glGetUniformiv__sig: 'viii',
glGetUniformiv: function(program, location, params) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glGetUniformiv', 'program');
+#endif
var data = Module.ctx.getUniform(GL.programs[program], GL.uniforms[location]);
if (typeof data == 'number' || typeof data == 'boolean') {
{{{ makeSetValue('params', '0', 'data', 'i32') }}};
@@ -751,6 +839,9 @@ var LibraryGL = {
glGetUniformLocation__sig: 'iii',
glGetUniformLocation: function(program, name) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glGetUniformLocation', 'program');
+#endif
name = Pointer_stringify(name);
var ptable = GL.uniformTable[program];
if (!ptable) ptable = GL.uniformTable[program] = {};
@@ -810,6 +901,9 @@ var LibraryGL = {
glGetActiveUniform__sig: 'viiiiiii',
glGetActiveUniform: function(program, index, bufSize, length, size, type, name) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glGetActiveUniform', 'program');
+#endif
program = GL.programs[program];
var info = Module.ctx.getActiveUniform(program, index);
@@ -1018,6 +1112,9 @@ var LibraryGL = {
glBindBuffer__sig: 'vii',
glBindBuffer: function(target, buffer) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.buffers, buffer, 'glBindBuffer', 'buffer');
+#endif
var bufferObj = buffer ? GL.buffers[buffer] : null;
if (target == Module.ctx.ARRAY_BUFFER) {
@@ -1062,6 +1159,9 @@ var LibraryGL = {
glGetActiveAttrib__sig: 'viiiiiii',
glGetActiveAttrib: function(program, index, bufSize, length, size, type, name) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glGetActiveAttrib', 'program');
+#endif
program = GL.programs[program];
var info = Module.ctx.getActiveAttrib(program, index);
@@ -1094,6 +1194,9 @@ var LibraryGL = {
glGetAttachedShaders__sig: 'viiii',
glGetAttachedShaders: function(program, maxCount, count, shaders) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glGetAttachedShaders', 'program');
+#endif
var result = Module.ctx.getAttachedShaders(GL.programs[program]);
var len = result.length;
if (len > maxCount) {
@@ -1109,12 +1212,18 @@ var LibraryGL = {
glShaderSource__sig: 'viiii',
glShaderSource: function(shader, count, string, length) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.shaders, shader, 'glShaderSource', 'shader');
+#endif
var source = GL.getSource(shader, count, string, length);
Module.ctx.shaderSource(GL.shaders[shader], source);
},
glGetShaderSource__sig: 'viiii',
glGetShaderSource: function(shader, bufSize, length, source) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.shaders, shader, 'glGetShaderSource', 'shader');
+#endif
var result = Module.ctx.getShaderSource(GL.shaders[shader]);
result = result.slice(0, Math.max(0, bufSize - 1));
writeStringToMemory(result, source);
@@ -1125,11 +1234,17 @@ var LibraryGL = {
glCompileShader__sig: 'vi',
glCompileShader: function(shader) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.shaders, shader, 'glCompileShader', 'shader');
+#endif
Module.ctx.compileShader(GL.shaders[shader]);
},
glGetShaderInfoLog__sig: 'viiii',
glGetShaderInfoLog: function(shader, maxLength, length, infoLog) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.shaders, shader, 'glGetShaderInfoLog', 'shader');
+#endif
var log = Module.ctx.getShaderInfoLog(GL.shaders[shader]);
// Work around a bug in Chromium which causes getShaderInfoLog to return null
if (!log) {
@@ -1144,6 +1259,9 @@ var LibraryGL = {
glGetShaderiv__sig: 'viii',
glGetShaderiv : function(shader, pname, p) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.shaders, shader, 'glGetShaderiv', 'shader');
+#endif
if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
{{{ makeSetValue('p', '0', 'Module.ctx.getShaderInfoLog(GL.shaders[shader]).length + 1', 'i32') }}};
} else {
@@ -1153,6 +1271,9 @@ var LibraryGL = {
glGetProgramiv__sig: 'viii',
glGetProgramiv : function(program, pname, p) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glGetProgramiv', 'program');
+#endif
if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH
{{{ makeSetValue('p', '0', 'Module.ctx.getProgramInfoLog(GL.programs[program]).length + 1', 'i32') }}};
} else {
@@ -1187,12 +1308,20 @@ var LibraryGL = {
glAttachShader__sig: 'vii',
glAttachShader: function(program, shader) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glAttachShader', 'program');
+ GL.validateGLObjectID(GL.shaders, shader, 'glAttachShader', 'shader');
+#endif
Module.ctx.attachShader(GL.programs[program],
GL.shaders[shader]);
},
glDetachShader__sig: 'vii',
glDetachShader: function(program, shader) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glDetachShader', 'program');
+ GL.validateGLObjectID(GL.shaders, shader, 'glDetachShader', 'shader');
+#endif
Module.ctx.detachShader(GL.programs[program],
GL.shaders[shader]);
},
@@ -1206,12 +1335,18 @@ var LibraryGL = {
glLinkProgram__sig: 'vi',
glLinkProgram: function(program) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glLinkProgram', 'program');
+#endif
Module.ctx.linkProgram(GL.programs[program]);
GL.uniformTable[program] = {}; // uniforms no longer keep the same names after linking
},
glGetProgramInfoLog__sig: 'viiii',
glGetProgramInfoLog: function(program, maxLength, length, infoLog) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glGetProgramInfoLog', 'program');
+#endif
var log = Module.ctx.getProgramInfoLog(GL.programs[program]);
// Work around a bug in Chromium which causes getProgramInfoLog to return null
if (!log) {
@@ -1226,11 +1361,17 @@ var LibraryGL = {
glUseProgram__sig: 'vi',
glUseProgram: function(program) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glUseProgram', 'program');
+#endif
Module.ctx.useProgram(program ? GL.programs[program] : null);
},
glValidateProgram__sig: 'vi',
glValidateProgram: function(program) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glValidateProgram', 'program');
+#endif
Module.ctx.validateProgram(GL.programs[program]);
},
@@ -1243,12 +1384,18 @@ var LibraryGL = {
glBindAttribLocation__sig: 'viii',
glBindAttribLocation: function(program, index, name) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.programs, program, 'glBindAttribLocation', 'program');
+#endif
name = Pointer_stringify(name);
Module.ctx.bindAttribLocation(GL.programs[program], index, name);
},
glBindFramebuffer__sig: 'vii',
glBindFramebuffer: function(target, framebuffer) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.framebuffers, framebuffer, 'glBindFramebuffer', 'framebuffer');
+#endif
Module.ctx.bindFramebuffer(target, framebuffer ? GL.framebuffers[framebuffer] : null);
},
@@ -1276,12 +1423,18 @@ var LibraryGL = {
glFramebufferRenderbuffer__sig: 'viiii',
glFramebufferRenderbuffer: function(target, attachment, renderbuffertarget, renderbuffer) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.renderbuffers, renderbuffer, 'glFramebufferRenderbuffer', 'renderbuffer');
+#endif
Module.ctx.framebufferRenderbuffer(target, attachment, renderbuffertarget,
GL.renderbuffers[renderbuffer]);
},
glFramebufferTexture2D__sig: 'viiiii',
glFramebufferTexture2D: function(target, attachment, textarget, texture, level) {
+#if GL_ASSERTIONS
+ GL.validateGLObjectID(GL.textures, texture, 'glFramebufferTexture2D', 'texture');
+#endif
Module.ctx.framebufferTexture2D(target, attachment, textarget,
GL.textures[texture], level);
},
@@ -3161,6 +3314,9 @@ var LibraryGL = {
var clientAttributes = GL.immediate.clientAttributes;
+#if GL_ASSERTIONS
+ GL.validateVertexAttribPointer(positionSize, positionType, GL.immediate.stride, clientAttributes[GL.immediate.VERTEX].offset);
+#endif
Module.ctx.vertexAttribPointer(this.positionLocation, positionSize, positionType, false,
GL.immediate.stride, clientAttributes[GL.immediate.VERTEX].offset);
Module.ctx.enableVertexAttribArray(this.positionLocation);
@@ -3173,6 +3329,9 @@ var LibraryGL = {
if (attribLoc === undefined || attribLoc < 0) continue;
if (texUnitID < textureSizes.length && textureSizes[texUnitID]) {
+#if GL_ASSERTIONS
+ GL.validateVertexAttribPointer(textureSizes[texUnitID], textureTypes[texUnitID], GL.immediate.stride, GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + texUnitID].offset);
+#endif
Module.ctx.vertexAttribPointer(attribLoc, textureSizes[texUnitID], textureTypes[texUnitID], false,
GL.immediate.stride, GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + texUnitID].offset);
Module.ctx.enableVertexAttribArray(attribLoc);
@@ -3189,6 +3348,9 @@ var LibraryGL = {
}
}
if (colorSize) {
+#if GL_ASSERTIONS
+ GL.validateVertexAttribPointer(colorSize, colorType, GL.immediate.stride, clientAttributes[GL.immediate.COLOR].offset);
+#endif
Module.ctx.vertexAttribPointer(this.colorLocation, colorSize, colorType, true,
GL.immediate.stride, clientAttributes[GL.immediate.COLOR].offset);
Module.ctx.enableVertexAttribArray(this.colorLocation);
@@ -3197,6 +3359,9 @@ var LibraryGL = {
Module.ctx.vertexAttrib4fv(this.colorLocation, GL.immediate.clientColor);
}
if (this.hasNormal) {
+#if GL_ASSERTIONS
+ GL.validateVertexAttribPointer(normalSize, normalType, GL.immediate.stride, clientAttributes[GL.immediate.NORMAL].offset);
+#endif
Module.ctx.vertexAttribPointer(this.normalLocation, normalSize, normalType, true,
GL.immediate.stride, clientAttributes[GL.immediate.NORMAL].offset);
Module.ctx.enableVertexAttribArray(this.normalLocation);
@@ -4176,6 +4341,9 @@ var LibraryGL = {
}
cb.clientside = false;
#endif
+#if GL_ASSERTIONS
+ GL.validateVertexAttribPointer(size, type, stride, ptr);
+#endif
Module.ctx.vertexAttribPointer(index, size, type, normalized, stride, ptr);
},