diff options
Diffstat (limited to 'src/library_gl.js')
-rw-r--r-- | src/library_gl.js | 168 |
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); }, |