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.js372
1 files changed, 354 insertions, 18 deletions
diff --git a/src/library_gl.js b/src/library_gl.js
index 9a63f5c0..f6fb2e27 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -29,6 +29,14 @@ var LibraryGL = {
#endif
return this.table[id];
},
+ id: function(obj) {
+ for (var i = 1; i < this.counter; ++i) {
+ if (obj == this.table[i]) {
+ return i;
+ }
+ }
+ return null;
+ },
remove: function(id) {
if( id == 0 ) return;
#if ASSERTIONS
@@ -44,11 +52,11 @@ var LibraryGL = {
glGetString: function(name_) {
switch(name_) {
- case Module.ctx.VENDOR:
- case Module.ctx.RENDERER:
- case Module.ctx.VERSION:
+ case 0x1F00 /* GL_VENDOR */:
+ case 0x1F01 /* GL_RENDERER */:
+ case 0x1F02 /* GL_VERSION */:
return allocate(intArrayFromString(Module.ctx.getParameter(name_)), 'i8', ALLOC_NORMAL);
- case 0x1F03: // Extensions
+ case 0x1F03 /* GL_EXTENSIONS */:
return allocate(intArrayFromString(Module.ctx.getSupportedExtensions().join(' ')), 'i8', ALLOC_NORMAL);
default:
throw 'Failure: Invalid glGetString value: ' + name_;
@@ -56,7 +64,125 @@ var LibraryGL = {
},
glGetIntegerv: function(name_, p) {
- {{{ makeSetValue('p', '0', 'Module.ctx.getParameter(name_)', 'i32') }}};
+ var result = Module.ctx.getParameter(name_);
+ switch (typeof(result)) {
+ case "number":
+ {{{ makeSetValue('p', '0', 'result', 'i32') }}};
+ break;
+ case "boolean":
+ {{{ makeSetValue('p', '0', 'result ? 1 : 0', 'i32') }}};
+ break;
+ case "string":
+ throw 'Native code calling glGetIntegerv(' + name_ + ') on a name which returns a string!';
+ case "object":
+ if (result === null) {
+ {{{ makeSetValue('p', '0', '0', 'i32') }}};
+ } else if (result instanceof Float32Array ||
+ result instanceof Uint32Array ||
+ result instanceof Int32Array ||
+ result instanceof Array) {
+ for (var i = 0; i < result.length; ++i) {
+ {{{ makeSetValue('p', 'i', 'result[i]', 'i32') }}};
+ }
+ } else if (result instanceof WebGLBuffer) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("buffer").id(result)', 'i32') }}};
+ } else if (result instanceof WebGLProgram) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("program").id(result)', 'i32') }}};
+ } else if (result instanceof WebGLFramebuffer) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("framebuffer").id(result)', 'i32') }}};
+ } else if (result instanceof WebGLRenderbuffer) {
+ {{{ makeSetValue('p', '0', 'gl.hashtable("renderbuffer").id(result)', 'i32') }}};
+ } else if (result instanceof WebGLTexture) {
+ {{{ makeSetValue('p', '0', 'gl.hashtable("texture").id(result)', 'i32') }}};
+ } else {
+ throw 'Unknown object returned from WebGL getParameter';
+ }
+ break;
+ case "undefined":
+ throw 'Native code calling glGetIntegerv(' + name_ + ') and it returns undefined';
+ default:
+ throw 'Why did we hit the default case?';
+ }
+ },
+
+ glGetFloatv: function(name_, p) {
+ var result = Module.ctx.getParameter(name_);
+ switch (typeof(result)) {
+ case "number":
+ {{{ makeSetValue('p', '0', 'result', 'float') }}};
+ break;
+ case "boolean":
+ {{{ makeSetValue('p', '0', 'result ? 1.0 : 0.0', 'float') }}};
+ break;
+ case "string":
+ {{{ makeSetValue('p', '0', '0', 'float') }}};
+ case "object":
+ if (result === null) {
+ throw 'Native code calling glGetFloatv(' + name_ + ') and it returns null';
+ } else if (result instanceof Float32Array ||
+ result instanceof Uint32Array ||
+ result instanceof Int32Array ||
+ result instanceof Array) {
+ for (var i = 0; i < result.length; ++i) {
+ {{{ makeSetValue('p', 'i', 'result[i]', 'float') }}};
+ }
+ } else if (result instanceof WebGLBuffer) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("buffer").id(result)', 'float') }}};
+ } else if (result instanceof WebGLProgram) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("program").id(result)', 'float') }}};
+ } else if (result instanceof WebGLFramebuffer) {
+ {{{ makeSetValue('p', '0', 'GL.hashtable("framebuffer").id(result)', 'float') }}};
+ } else if (result instanceof WebGLRenderbuffer) {
+ {{{ makeSetValue('p', '0', 'gl.hashtable("renderbuffer").id(result)', 'float') }}};
+ } else if (result instanceof WebGLTexture) {
+ {{{ makeSetValue('p', '0', 'gl.hashtable("texture").id(result)', 'float') }}};
+ } else {
+ throw 'Unknown object returned from WebGL getParameter';
+ }
+ break;
+ case "undefined":
+ throw 'Native code calling glGetFloatv(' + name_ + ') and it returns undefined';
+ default:
+ throw 'Why did we hit the default case?';
+ }
+ },
+
+ glGetBooleanv: function(name_, p) {
+ var result = Module.ctx.getParameter(name_);
+ switch (typeof(result)) {
+ case "number":
+ {{{ makeSetValue('p', '0', 'result != 0', 'i8') }}};
+ break;
+ case "boolean":
+ {{{ makeSetValue('p', '0', 'result != 0', 'i8') }}};
+ break;
+ case "string":
+ throw 'Native code calling glGetBooleanv(' + name_ + ') on a name which returns a string!';
+ case "object":
+ if (result === null) {
+ {{{ makeSetValue('p', '0', '0', 'i8') }}};
+ } else if (result instanceof Float32Array ||
+ result instanceof Uint32Array ||
+ result instanceof Int32Array ||
+ result instanceof Array) {
+ for (var i = 0; i < result.length; ++i) {
+ {{{ makeSetValue('p', 'i', 'result[i] != 0', 'i8') }}};
+ }
+ } else if (result instanceof WebGLBuffer ||
+ result instanceof WebGLProgram ||
+ result instanceof WebGLFramebuffer ||
+ result instanceof WebGLRenderbuffer ||
+ result instanceof WebGLTexture) {
+ {{{ makeSetValue('p', '0', '1', 'i8') }}}; // non-zero ID is always 1!
+ } else {
+ throw 'Unknown object returned from WebGL getParameter';
+ }
+ break;
+ case "undefined":
+ throw 'Unknown object returned from WebGL getParameter';
+ default:
+ throw 'Why did we hit the default case?';
+ }
},
glGenTextures__deps: ['$GL'],
@@ -75,16 +201,98 @@ var LibraryGL = {
}
},
+ glCompressedTexImage2D: function(target, level, internalformat, width, height, border, imageSize, data) {
+ if (data) {
+ data = new Uint8Array(Array_copy(data, imageSize));
+ } else {
+ data = null;
+ }
+ Module.ctx.compressedTexImage2D(target, level, internalformat, width, height, border, data);
+ },
+
+ glCompressedTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, imageSize, data) {
+ if (data) {
+ data = new Uint8Array(Array_copy(data, imageSize));
+ } else {
+ data = null;
+ }
+ Module.ctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, data);
+ },
+
glTexImage2D: function(target, level, internalformat, width, height, border, format, type, pixels) {
if (pixels) {
- pixels = new Uint8Array(Array_copy(pixels, pixels + width*height*4)); // TODO: optimize
+ var sizePerPixel;
+ switch (type) {
+ case 0x1401 /* GL_UNSIGNED_BYTE */:
+ switch (format) {
+ case 0x1906 /* GL_ALPHA */:
+ case 0x1909 /* GL_LUMINANCE */:
+ sizePerPixel = 1;
+ break;
+ case 0x1907 /* GL_RGB */:
+ sizePerPixel = 3;
+ break;
+ case 0x1908 /* GL_RGBA */:
+ sizePerPixel = 4;
+ break;
+ case 0x190A /* GL_LUMINANCE_ALPHA */:
+ sizePerPixel = 2;
+ break;
+ default:
+ throw 'Invalid format (' + format + ') passed to glTexImage2D';
+ }
+ pixels = new Uint8Array(Array_copy(pixels, width*height*sizePerPixel));
+ 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 */:
+ sizePerPixel = 2;
+ pixels = new Uint16Array(new ArrayBuffer(Array_copy(pixels, width*height*sizePerPixel*2)));
+ break;
+ default:
+ throw 'Invalid type (' + type + ') passed to glTexImage2D';
+ }
+ } else {
+ pixels = null;
}
Module.ctx.texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
},
glTexSubImage2D: function(target, level, xoffset, yoffset, width, height, format, type, pixels) {
if (pixels) {
- pixels = new Uint8Array(Array_copy(pixels, pixels + width*height*4)); // TODO: optimize
+ var sizePerPixel;
+ switch (type) {
+ case 0x1401 /* GL_UNSIGNED_BYTE */:
+ switch (format) {
+ case 0x1906 /* GL_ALPHA */:
+ case 0x1909 /* GL_LUMINANCE */:
+ sizePerPixel = 1;
+ break;
+ case 0x1907 /* GL_RGB */:
+ sizePerPixel = 3;
+ break;
+ case 0x1908 /* GL_RGBA */:
+ sizePerPixel = 4;
+ break;
+ case 0x190A /* GL_LUMINANCE_ALPHA */:
+ sizePerPixel = 2;
+ break;
+ default:
+ throw 'Invalid format (' + format + ') passed to glTexSubImage2D';
+ }
+ pixels = new Uint8Array(Array_copy(pixels, (width-xoffset+1)*(height-yoffset+1)*sizePerPixel));
+ 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 */:
+ sizePerPixel = 2;
+ pixels = new Uint16Array(new ArrayBuffer(Array_copy(pixels, (width-xoffset+1)*(height-yoffset+1)*sizePerPixel*2)));
+ break;
+ default:
+ throw 'Invalid type (' + type + ') passed to glTexSubImage2D';
+ }
+ } else {
+ pixels = null;
}
Module.ctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
},
@@ -93,6 +301,23 @@ var LibraryGL = {
Module.ctx.bindTexture(target, GL.hashtable("texture").get(texture));
},
+ glGetTexParameterfv: function(target, pname, params) {
+ {{{ makeSetValue('params', '0', 'Module.getTexParameter(target, pname)', 'float') }}};
+ },
+
+ glGetTexParameteriv: function(target, pname, params) {
+ {{{ makeSetValue('params', '0', 'Module.getTexParameter(target, pname)', 'i32') }}};
+ },
+
+ glIsTexture_deps: ['$GL'],
+ glIsTexture: function(texture) {
+ var fb = GL.hashtable("texture").get(texture);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isTexture(fb);
+ },
+
glGenBuffers__deps: ['$GL'],
glGenBuffers: function(n, buffers) {
for (var i = 0; i < n; i++) {
@@ -114,6 +339,53 @@ var LibraryGL = {
Module.ctx.bufferData(target, floatArray, usage);
},
+ glBufferSubData: function(target, offset, size, data) {
+ var floatArray = new Float32Array(TypedArray_copy(data, size, offset));
+ Module.ctx.bufferSubData(target, offset, floatArray);
+ },
+
+ glIsBuffer_deps: ['$GL'],
+ glIsBuffer: function(buffer) {
+ var fb = GL.hashtable("buffer").get(buffer);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isBuffer(fb);
+ },
+
+ glGenRenderbuffers__deps: ['$GL'],
+ glGenRenderbuffers: function(n, renderbuffers) {
+ for (var i = 0; i < n; i++) {
+ var id = GL.hashtable("renderbuffer").add(Module.ctx.createRenderbuffer());
+ {{{ makeSetValue('renderbuffers', 'i', 'id', 'i32') }}};
+ }
+ },
+
+ glDeleteRenderbuffers: function(n, renderbuffers) {
+ for (var i = 0; i < n; i++) {
+ var id = {{{ makeGetValue('renderbuffers', 'i', 'i32') }}};
+ Module.ctx.deleteRenderbuffer(GL.hashtable("renderbuffer").get(id));
+ GL.hashtable("renderbuffer").remove(id);
+ }
+ },
+
+ glBindRenderbuffer: function(target, renderbuffer) {
+ Module.ctx.bindRenderbuffer(target, GL.hashtable("renderbuffer").get(renderbuffer));
+ },
+
+ glGetRenderbufferParameteriv: function(target, pname, params) {
+ {{{ makeSetValue('params', '0', 'Module.ctx.getRenderbufferParameter(target, pname)', 'i32') }}};
+ },
+
+ glIsRenderbuffer_deps: ['$GL'],
+ glIsRenderbuffer: function(renderbuffer) {
+ var fb = GL.hashtable("renderbuffer").get(renderbuffer);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isRenderbuffer(fb);
+ },
+
glBindAttribLocation_deps: ['$GL'],
glGetUniformLocation: function(program, name) {
name = Pointer_stringify(name);
@@ -272,6 +544,27 @@ var LibraryGL = {
return GL.hashtable("shader").add(shader);
},
+ glDeleteShader: function(shader) {
+ Module.ctx.deleteShader(GL.hashtable("shader").get(shader));
+ },
+
+ glDetachShader: function(program, shader) {
+ Module.ctx.detachShader(GL.hashtable("program").get(program),
+ GL.hashtable("shader").get(shader));
+ },
+
+ glGetAttachedShaders: function(program, maxCount, count, shaders) {
+ var result = Module.ctx.getAttachedShaders(GL.hashtable("program").get(program));
+ var len = result.length;
+ if (len > maxCount) {
+ len = maxCount;
+ }
+ {{{ makeSetValue('count', '0', 'len', 'i32') }}};
+ for (var i = 0; i < len; ++i) {
+ {{{ makeSetValue('shaders', 'i', 'GL.hashtable("shader").get(result[i])', 'i32') }}};
+ }
+ },
+
glShaderSource_deps: ['$GL'],
glShaderSource: function(shader, count, string, length) {
var source = "";
@@ -295,6 +588,15 @@ var LibraryGL = {
Module.ctx.shaderSource(GL.hashtable("shader").get(shader), source);
},
+ glGetShaderSource: function(shader, bufsize, length, source) {
+ var result = Module.ctx.getShaderSource(GL.hashtable("shader").get(shader));
+ result.slice(0, bufsize - 1);
+ writeStringToMemory(result, source);
+ if (length) {
+ {{{ makeSetValue('length', '0', 'result.length', 'i32') }}};
+ }
+ },
+
glCompileShader_deps: ['$GL'],
glCompileShader: function(shader) {
Module.ctx.compileShader(GL.hashtable("shader").get(shader));
@@ -306,18 +608,27 @@ var LibraryGL = {
log.slice(0, maxLength - 1);
writeStringToMemory(log, infoLog);
if (length) {
- {{{ makeSetValue('length', 'i', 'log.length', 'i32') }}}
+ {{{ makeSetValue('length', '0', 'log.length', 'i32') }}}
}
},
-
+
glGetShaderiv_deps: ['$GL'],
- glGetShaderiv : function(shader, pname, p) {
- {{{ makeSetValue('p', '0', 'Module.ctx.getShaderParameter(GL.hashtable("shader").get(shader),pname)', 'i32') }}};
+ glGetShaderiv : function(shader, pname, p) {
+ {{{ makeSetValue('p', '0', 'Module.ctx.getShaderParameter(GL.hashtable("shader").get(shader), pname)', 'i32') }}};
},
glGetProgramiv_deps: ['$GL'],
- glGetProgramiv : function(program, pname, p) {
- {{{ makeSetValue('p', '0', 'Module.ctx.getProgramParameter(GL.hashtable("program").get(program),pname)', 'i32') }}};
+ glGetProgramiv : function(program, pname, p) {
+ {{{ makeSetValue('p', '0', 'Module.ctx.getProgramParameter(GL.hashtable("program").get(program), pname)', 'i32') }}};
+ },
+
+ glIsShader_deps: ['$GL'],
+ glIsShader: function(shader) {
+ var fb = GL.hashtable("shader").get(shader);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isShader(fb);
},
glCreateProgram_deps: ['$GL'],
@@ -325,12 +636,23 @@ var LibraryGL = {
return GL.hashtable("program").add(Module.ctx.createProgram());
},
+ glDeleteProgram: function(program) {
+ Module.ctx.deleteProgram(GL.hashtable("program").get(program));
+ },
+
glAttachShader_deps: ['$GL'],
glAttachShader: function(program, shader) {
Module.ctx.attachShader(GL.hashtable("program").get(program),
GL.hashtable("shader").get(shader));
},
+ glGetShaderPrecisionFormat: function(shaderType, precisionType, range, precision) {
+ var result = Module.ctx.getShaderPrecisionFormat(shaderType, precisionType);
+ {{{ makeSetValue('range', '0', 'result.rangeMin', 'i32') }}};
+ {{{ makeSetValue('range', '1', 'result.rangeMax', 'i32') }}};
+ {{{ makeSetValue('precision', '0', 'result.precision', 'i32') }}};
+ },
+
glLinkProgram_deps: ['$GL'],
glLinkProgram: function(program) {
Module.ctx.linkProgram(GL.hashtable("program").get(program));
@@ -346,7 +668,7 @@ var LibraryGL = {
log = log.substr(0, maxLength - 1);
writeStringToMemory(log, infoLog);
if (length) {
- {{{ makeSetValue('length', 'i', 'log.length', 'i32') }}}
+ {{{ makeSetValue('length', '0', 'log.length', 'i32') }}}
}
},
@@ -355,6 +677,20 @@ var LibraryGL = {
Module.ctx.useProgram(GL.hashtable("program").get(program));
},
+ glValidateProgram_deps: ['$Gl'],
+ glValidateProgram: function(program) {
+ Module.ctx.validateProgram(GL.hashtable("program").get(program));
+ },
+
+ glIsProgram_deps: ['$GL'],
+ glIsProgram: function(program) {
+ var fb = GL.hashtable("program").get(program);
+ if (typeof(fb) == 'undefined') {
+ return false;
+ }
+ return Module.ctx.isProgram(fb);
+ },
+
glBindAttribLocation_deps: ['$GL'],
glBindAttribLocation: function(program, index, name) {
name = Pointer_stringify(name);
@@ -414,12 +750,12 @@ var LibraryGL = {
// Simple pass-through functions
[[0, 'shadeModel fogi fogfv getError finish flush'],
- [1, 'clearDepth depthFunc enable disable frontFace cullFace clear enableVertexAttribArray disableVertexAttribArray lineWidth clearStencil depthMask stencilMask stencilMaskSeparate checkFramebufferStatus activeTexture'],
- [2, 'pixelStorei vertexAttrib1f depthRange polygonOffset blendFunc'],
+ [1, 'clearDepth depthFunc enable disable frontFace cullFace clear enableVertexAttribArray disableVertexAttribArray lineWidth clearStencil depthMask stencilMask stencilMaskSeparate checkFramebufferStatus generateMipmap activeTexture'],
[3, 'texParameteri texParameterf drawArrays vertexAttrib2f'],
- [4, 'viewport clearColor scissor vertexAttrib3f colorMask drawElements'],
+ [4, 'viewport clearColor scissor vertexAttrib3f colorMask drawElements renderbufferStorage'],
[5, 'vertexAttrib4f'],
- [6, 'vertexAttribPointer']].forEach(function(data) {
+ [6, 'vertexAttribPointer'],
+ [8, 'copyTexImage2D copyTexSubImage2D']].forEach(function(data) {
var num = data[0];
var names = data[1];
var args = range(num).map(function(i) { return 'x' + i }).join(', ');