diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-01-28 21:29:02 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-01-28 21:29:02 -0800 |
commit | 687b8cfa3d105a634b3c9cfbc5fc287f1517fae3 (patch) | |
tree | eea2952d7673296ba6a8cd2384061fc3ad270473 | |
parent | c516fa7758636e15a7077c658db3c74533c7ee38 (diff) | |
parent | b6ebeed2cfcebb220f2ce700c7cbe484e62cd2e2 (diff) |
Merge branch 'master' into llvmopts
-rwxr-xr-x | emcc | 15 | ||||
-rw-r--r-- | src/library.js | 42 | ||||
-rw-r--r-- | src/library_gl.js | 481 | ||||
-rw-r--r-- | src/library_sdl.js | 15 | ||||
-rw-r--r-- | src/preamble.js | 39 | ||||
-rw-r--r-- | src/shell.html | 5 | ||||
-rw-r--r-- | system/include/GL/freeglut_std.h | 628 | ||||
-rw-r--r-- | system/include/GL/glut.h | 21 | ||||
-rw-r--r-- | system/include/GLES2/gl2.h | 621 | ||||
-rw-r--r-- | system/include/GLES2/gl2platform.h | 30 | ||||
-rw-r--r-- | system/include/KHR/khrplatform.h | 277 | ||||
-rw-r--r-- | tests/hello_world_gles.c | 729 | ||||
-rw-r--r-- | tests/hello_world_gles_shell.html | 55 | ||||
-rwxr-xr-x | tests/runner.py | 140 |
14 files changed, 3028 insertions, 70 deletions
@@ -169,6 +169,13 @@ Options that are modified or new in %s include: will be run). Note that this by itself will not minify the code (closure does that) + --shell-path <path> The path name to a skeleton HTML file used + when generating HTML output. The shell file + used needs to have this token inside it: + {{{ SCRIPT_CODE }}} + Note that this argument is ignored if a + target other than HTML is specified using + the -o option. The target file, if specified (-o <target>), defines what will be generated: @@ -285,6 +292,7 @@ try: closure = None js_transform = None compress_whitespace = None + shell_path = shared.path_from_root('src', 'shell.html') def check_bad_eq(arg): assert '=' not in arg, 'Invalid parameter (do not use "=" with "--" options)' @@ -323,6 +331,11 @@ try: f.close() newargs[i] = '' newargs[i+1] = '' + elif newargs[i].startswith('--shell-file'): + check_bad_eq(newargs[i]) + shell_path = newargs[i+1] + newargs[i] = '' + newargs[i+1] = '' newargs = [ arg for arg in newargs if arg is not '' ] if llvm_opts is None: llvm_opts = 1 if opt_level >= 1 else 0 @@ -634,7 +647,7 @@ try: # If we were asked to also generate HTML, do that if final_suffix == 'html': if DEBUG: print >> sys.stderr, 'emcc: generating HTML' - shell = open(shared.path_from_root('src', 'shell.html')).read() + shell = open(shell_path).read() html = open(target, 'w') html.write(shell.replace('{{{ SCRIPT_CODE }}}', open(final).read())) html.close() diff --git a/src/library.js b/src/library.js index ad1ff696..47e15aae 100644 --- a/src/library.js +++ b/src/library.js @@ -4687,6 +4687,34 @@ LibraryManager.library = { }, nanf: 'nan', + sincos: function(x, sine, cosine) { + var sineVal = Math.sin(x), + cosineVal = Math.cos(x); + {{{ makeSetValue('sine', '0', 'sineVal', 'double') }}}; + {{{ makeSetValue('cosine', '0', 'cosineVal', 'double') }}}; + }, + + sincosf: function(x, sine, cosine) { + var sineVal = Math.sin(x), + cosineVal = Math.cos(x); + {{{ makeSetValue('sine', '0', 'sineVal', 'float') }}}; + {{{ makeSetValue('cosine', '0', 'cosineVal', 'float') }}}; + }, + + __div_t_struct_layout: Runtime.generateStructInfo([ + ['i32', 'quot'], + ['i32', 'rem'], + ]), + div__deps: ['__div_t_struct_layout'], + div: function(divt, numer, denom) { + var quot = Math.floor(numer / denom); + var rem = numer - quot * denom; + var offset = ___div_t_struct_layout.rem; + {{{ makeSetValue('divt', '0', 'quot', 'i32') }}}; + {{{ makeSetValue('divt', 'offset', 'rem', 'i32') }}}; + return divt; + }, + __fpclassifyf: function(x) { if (isNaN(x)) return {{{ cDefine('FP_NAN') }}}; if (!isFinite(x)) return {{{ cDefine('FP_INFINITE') }}}; @@ -5720,6 +5748,20 @@ LibraryManager.library = { }, // ========================================================================== + // arpa/inet.h + // ========================================================================== + + htonl: function(value) { + return ((value & 0xff) << 24) + ((value & 0xff00) << 8) + + ((value & 0xff0000) >> 8) + ((value & 0xff000000) >> 24); + }, + htons: function(value) { + return ((value & 0xff) << 8) + ((value & 0xff00) >> 8); + }, + ntohl: 'htonl', + ntohs: 'htons', + + // ========================================================================== // emscripten.h // ========================================================================== diff --git a/src/library_gl.js b/src/library_gl.js index 2be881df..e1a7c73b 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -4,8 +4,35 @@ var LibraryGL = { $GL: { - textures: {}, - textureCounter: 0, + hashtable: function(name) { + if (!this._hashtables) { + this._hashtables = {}; + } + if (!(name in this._hashtables)) { + this._hashtables[name] = { + table: {}, + counter: 0, + add: function(obj) { + var id = this.counter++; + this.table[id] = obj; + return id; + }, + get: function(id) { +#if ASSERTIONS + assert(id < this.counter, "Invalid id " + id + " for the hashtable " + name); +#endif + return this.table[id]; + }, + remove: function(id) { +#if ASSERTIONS + assert(id < this.counter, "Invalid id " + id + " for the hashtable " + name); +#endif + delete this.table[id]; + } + }; + } + return this._hashtables[name]; + }, }, glGetString: function(name_) { @@ -24,7 +51,7 @@ var LibraryGL = { glGetIntegerv: function(name_, p) { switch(name_) { case Module.ctx.MAX_TEXTURE_SIZE: - IHEAP[p] = Module.ctx.getParameter(name_); + {{{ makeSetValue('p', '0', 'Module.ctx.getParameter(name_)', 'i32') }}}; break; default: throw 'Failure: Invalid glGetIntegerv value: ' + name_; @@ -34,78 +61,476 @@ var LibraryGL = { glGenTextures__deps: ['$GL'], glGenTextures: function(n, textures) { for (var i = 0; i < n; i++) { - var id = GL.textureCounter++; - GL.textures[id] = Module.ctx.createTexture(); - IHEAP[textures+QUANTUM_SIZE*i] = id; + var id = GL.hashtable("texture").add(Module.ctx.createTexture()); + {{{ makeSetValue('textures', 'i', 'id', 'i32') }}}; } }, glDeleteTextures: function(n, textures) { for (var i = 0; i < n; i++) { - var id = IHEAP[textures+QUANTUM_SIZE*i]; - Module.ctx.deleteTexture(GL.textures[id]); - delete GL.textures[id]; + var id = {{{ makeGetValue('textures', 'i', 'i32') }}}; + Module.ctx.deleteTexture(GL.hashtable("texture").get(id)); + GL.hashtable("texture").remove(id); } }, glTexImage2D: function(target, level, internalformat, width, height, border, format, type, pixels) { if (pixels) { - pixels = new Uint8Array(IHEAP.slice(pixels, pixels + width*height*4)); // TODO: optimize + pixels = new Uint8Array(Array_copy(pixels, pixels + width*height*4)); // TODO: optimize } 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(IHEAP.slice(pixels, pixels + width*height*4)); // TODO: optimize + pixels = new Uint8Array(Array_copy(pixels, pixels + width*height*4)); // TODO: optimize } Module.ctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); }, glBindTexture: function(target, texture) { - Module.ctx.bindTexture(target, GL.textures[texture]); + Module.ctx.bindTexture(target, GL.hashtable("texture").get(texture)); }, - glClearColor: function(red, green, blue, alpha) { - Module.ctx.clearColor(red, green, blue, alpha); + glGenBuffers__deps: ['$GL'], + glGenBuffers: function(n, buffers) { + for (var i = 0; i < n; i++) { + var id = GL.hashtable("buffer").add(Module.ctx.createBuffer()); + {{{ makeSetValue('buffers', 'i', 'id', 'i32') }}}; + } + }, + + glDeleteBuffers: function(n, buffers) { + for (var i = 0; i < n; i++) { + var id = {{{ makeGetValue('buffers', 'i', 'i32') }}}; + Module.ctx.deleteBuffer(GL.hashtable("buffer").get(id)); + GL.hashtable("buffer").remove(id); + } + }, + + glBufferData: function(target, size, data, usage) { + var floatArray = new Float32Array(TypedArray_copy(data, size)); + Module.ctx.bufferData(target, floatArray, usage); + }, + + glBindAttribLocation_deps: ['$GL'], + glGetUniformLocation: function(program, name) { + name = Pointer_stringify(name); + return GL.hashtable("uniform").add( + Module.ctx.getUniformLocation(GL.hashtable("program").get(program), name)); + }, + + glUniform1f: function(Location, v0) { + Location = GL.hashtable("uniform").get(Location); + Module.ctx.uniform1f(Location, v0); + }, + + glUniform2f: function(Location, v0, v1) { + Location = GL.hashtable("uniform").get(Location); + Module.ctx.uniform2f(Location, v0, v1); + }, + + glUniform3f: function(Location, v0, v1, v2) { + Location = GL.hashtable("uniform").get(Location); + Module.ctx.uniform3f(Location, v0, v1, v2); }, - glClear: function(mask) { - Module.ctx.clear(mask); + glUniform4f: function(Location, v0, v1, v2, v3) { + Location = GL.hashtable("uniform").get(Location); + Module.ctx.uniform4f(Location, v0, v1, v2, v3); }, - glEnable: function(cap) { - Module.ctx.enable(cap); + glUniform1i: function(Location, v0) { + Location = GL.hashtable("uniform").get(Location); + Module.ctx.uniform1i(Location, v0); }, - glScissor: function(x, y, width, height) { - Module.ctx.scissor(x, y, width, height); + glUniform2i: function(Location, v0, v1) { + Location = GL.hashtable("uniform").get(Location); + Module.ctx.uniform2i(Location, v0, v1); + }, + + glUniform3i: function(Location, v0, v1, v2) { + Location = GL.hashtable("uniform").get(Location); + Module.ctx.uniform3i(Location, v0, v1, v2); + }, + + glUniform4i: function(Location, v0, v1, v2, v3) { + Location = GL.hashtable("uniform").get(Location); + Module.ctx.uniform4i(Location, v0, v1, v2, v3); + }, + + glUniform1fv: function(Location, count, value) { + Location = GL.hashtable("uniform").get(Location); + value = new Float32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniform1fv(Location, value); + }, + + glUniform2fv: function(Location, count, value) { + Location = GL.hashtable("uniform").get(Location); + count *= 2; + value = new Float32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniform2fv(Location, value); + }, + + glUniform3fv: function(Location, count, value) { + Location = GL.hashtable("uniform").get(Location); + count *= 3; + value = new Float32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniform3fv(Location, value); + }, + + glUniform4fv: function(Location, count, value) { + Location = GL.hashtable("uniform").get(Location); + count *= 4; + value = new Float32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniform4fv(Location, value); + }, + + glUniform1fi: function(Location, count, value) { + Location = GL.hashtable("uniform").get(Location); + value = new Uint32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniform1fi(Location, value); + }, + + glUniform2fi: function(Location, count, value) { + Location = GL.hashtable("uniform").get(Location); + count *= 2; + value = new Uint32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniform2fi(Location, value); + }, + + glUniform3fi: function(Location, count, value) { + Location = GL.hashtable("uniform").get(Location); + count *= 3; + value = new Uint32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniform3fi(Location, value); + }, + + glUniform4fi: function(Location, count, value) { + Location = GL.hashtable("uniform").get(Location); + count *= 4; + value = new Uint32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniform4fi(Location, value); + }, + + glUniformMatrix2fv: function(Location, count, transpose, value) { + Location = GL.hashtable("uniform").get(Location); + count *= 4; + value = new Float32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniformMatrix2fv(Location, transpose, value); + }, + + glUniformMatrix3fv: function(Location, count, transpose, value) { + Location = GL.hashtable("uniform").get(Location); + count *= 9; + value = new Float32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniformMatrix3fv(Location, transpose, value); + }, + + glUniformMatrix4fv: function(Location, count, transpose, value) { + Location = GL.hashtable("uniform").get(Location); + count *= 16; + value = new Float32Array(TypedArray_copy(value, count*4)); // TODO: optimize + Module.ctx.uniformMatrix4fv(Location, transpose, value); + }, + + glBindBuffer: function(target, buffer) { + Module.ctx.bindBuffer(target, GL.hashtable("buffer").get(buffer)); + }, + + glVertexAttrib1f: function(index, v0) { + Module.ctx.vertexAttrib1f(index, v0); + }, + + glVertexAttrib2f: function(index, v0, v1) { + Module.ctx.vertexAttrib2f(index, v0, v1); + }, + + glVertexAttrib3f: function(index, v0, v1, v2) { + Module.ctx.vertexAttrib3f(index, v0, v1, v2); + }, + + glVertexAttrib4f: function(index, v0, v1, v2, v3) { + Module.ctx.vertexAttrib4f(index, v0, v1, v2, v3); + }, + + glVertexAttrib1fv: function(index, v) { + v = new Float32Array(TypedArray_copy(v, 1*4)); // TODO: optimize + Module.ctx.vertexAttrib1fv(index, v); + }, + + glVertexAttrib2fv: function(index, v) { + v = new Float32Array(TypedArray_copy(v, 2*4)); // TODO: optimize + Module.ctx.vertexAttrib2fv(index, v); + }, + + glVertexAttrib3fv: function(index, v) { + v = new Float32Array(TypedArray_copy(v, 3*4)); // TODO: optimize + Module.ctx.vertexAttrib3fv(index, v); + }, + + glVertexAttrib4fv: function(index, v) { + v = new Float32Array(TypedArray_copy(v, 4*4)); // TODO: optimize + Module.ctx.vertexAttrib4fv(index, v); + }, + + glVertexAttribPointer: function(index, size, type, normalized, stride, pointer) { + Module.ctx.vertexAttribPointer(index, size, type, normalized, stride, pointer); + }, + + glEnableVertexAttribArray: function(index) { + Module.ctx.enableVertexAttribArray(index); + }, + + glDisableVertexAttribArray: function(index) { + Module.ctx.disableVertexAttribArray(index); + }, + + glDrawArrays: function(mode, first, count) { + Module.ctx.drawArrays(mode, first, count); + }, + + glGetAttribLocation: function(program, name) { + program = GL.hashtable("program").get(program); + name = Pointer_stringify(name); + Module.ctx.getAttribLocation(program, name); + }, + + glCreateShader_deps: ['$GL'], + glCreateShader: function(shaderType) { + var shader = Module.ctx.createShader(shaderType); + return GL.hashtable("shader").add(shader); + }, + + glShaderSource_deps: ['$GL'], + glShaderSource: function(shader, count, string, length) { + var source = ""; + for (var i = 0; i < count; ++i) { + var frag = string[i]; + if (length) { + var len = {{{ makeGetValue('length', 'i', 'i32') }}}; + if (len < 0) { + frag = Pointer_stringify({{{ makeGetValue('string', 'i', 'i32') }}}); + } else { + frag = Pointer_stringify({{{ makeGetValue('string', 'i', 'i32') }}}, len); + } + } else { + frag = Pointer_stringify({{{ makeGetValue('string', 'i', 'i32') }}}); + } + if (source.length) { + source += "\n"; + } + source += frag; + } + Module.ctx.shaderSource(GL.hashtable("shader").get(shader), source); + }, + + glCompileShader_deps: ['$GL'], + glCompileShader: function(shader) { + Module.ctx.compileShader(GL.hashtable("shader").get(shader)); + }, + + glGetShaderInfoLog_deps: ['$GL'], + glGetShaderInfoLog: function(shader, maxLength, length, infoLog) { + var log = Module.ctx.getShaderInfoLog(GL.hashtable("shader").get(shader)); + log.slice(0, maxLength - 1); + writeStringToMemory(log, infoLog); + if (length) { + {{{ makeSetValue('length', 'i', 'log.length', 'i32') }}} + } + }, + + glCreateProgram_deps: ['$GL'], + glCreateProgram: function() { + return GL.hashtable("program").add(Module.ctx.createProgram()); + }, + + glAttachShader_deps: ['$GL'], + glAttachShader: function(program, shader) { + Module.ctx.attachShader(GL.hashtable("program").get(program), + GL.hashtable("shader").get(shader)); + }, + + glLinkProgram_deps: ['$GL'], + glLinkProgram: function(program) { + Module.ctx.linkProgram(GL.hashtable("program").get(program)); + }, + + glGetProgramInfoLog_deps: ['$GL'], + glGetProgramInfoLog: function(program, maxLength, length, infoLog) { + var log = Module.ctx.getProgramInfoLog(GL.hashtable("program").get(program)); + // Work around a bug in Chromium which causes getProgramInfoLog to return null + if (!log) { + log = ""; + } + log = log.substr(0, maxLength - 1); + writeStringToMemory(log, infoLog); + if (length) { + {{{ makeSetValue('length', 'i', 'log.length', 'i32') }}} + } + }, + + glUseProgram_deps: ['$Gl'], + glUseProgram: function(program) { + Module.ctx.useProgram(GL.hashtable("program").get(program)); + }, + + glBindAttribLocation_deps: ['$GL'], + glBindAttribLocation: function(program, index, name) { + name = Pointer_stringify(name); + Module.ctx.bindAttribLocation(GL.hashtable("program").get(program), index, name); }, }; -// Ignored stubs for fixed-function pipeline. We will need to emulate this -'begin end matrixMode loadIdentity ortho color3f texCoord2f vertex2f blendFunc pushMatrix popMatrix translatef scalef color4ub enableClientState disableClientState vertexPointer colorPointer normalPointer texCoordPointer drawArrays clientActiveTexture_'.split(' ').forEach(function(name_) { - var cName = 'gl' + name_[0].toUpperCase() + name_.substr(1); - LibraryGL[cName] = function(){}; -}); // Simple pass-through functions -[[0, 'shadeModel fogi fogfv'], - [1, 'clearDepth depthFunc enable disable frontFace cullFace'], +[[0, 'shadeModel fogi fogfv getError'], + [1, 'clearDepth depthFunc enable disable frontFace cullFace clear'], [2, 'pixelStorei'], [3, 'texParameteri texParameterf'], - [4, 'viewport clearColor']].forEach(function(data) { + [4, 'viewport clearColor scissor']].forEach(function(data) { var num = data[0]; var names = data[1]; var args = range(num).map(function(i) { return 'x' + i }).join(', '); var stub = '(function(' + args + ') { ' + (num > 0 ? 'Module.ctx.NAME(' + args + ')' : '') + ' })'; names.split(' ').forEach(function(name_) { var cName = 'gl' + name_[0].toUpperCase() + name_.substr(1); +#if ASSERTIONS + assert(!(cName in LibraryGL), "Cannot reimplement the existing function " + cName); +#endif LibraryGL[cName] = eval(stub.replace('NAME', name_)); //print(cName + ': ' + LibraryGL[cName]); }); }); +var LibraryGLUT = { + $GLUT: { + initTime: null, + idleFunc: null, + keyboardFunc: null, + reshapeFunc: null, + lastX: 0, + lastY: 0, + + onMousemove: function(event) { + GLUT.lastX = event['clientX']; + GLUT.lastY = event['clientY']; + }, + + onKeydown: function(event) { + if (GLUT.keyboardFunc) { + var key = null; + switch (event['keyCode']) { + case 0x70 /*DOM_VK_F1*/: key = 1 /* GLUT_KEY_F1 */; break; + case 0x71 /*DOM_VK_F2*/: key = 2 /* GLUT_KEY_F2 */; break; + case 0x72 /*DOM_VK_F3*/: key = 3 /* GLUT_KEY_F3 */; break; + case 0x73 /*DOM_VK_F4*/: key = 4 /* GLUT_KEY_F4 */; break; + case 0x74 /*DOM_VK_F5*/: key = 5 /* GLUT_KEY_F5 */; break; + case 0x75 /*DOM_VK_F6*/: key = 6 /* GLUT_KEY_F6 */; break; + case 0x76 /*DOM_VK_F7*/: key = 7 /* GLUT_KEY_F7 */; break; + case 0x77 /*DOM_VK_F8*/: key = 8 /* GLUT_KEY_F8 */; break; + case 0x78 /*DOM_VK_F9*/: key = 9 /* GLUT_KEY_F9 */; break; + case 0x79 /*DOM_VK_F10*/: key = 10 /* GLUT_KEY_F10 */; break; + case 0x7a /*DOM_VK_F11*/: key = 11 /* GLUT_KEY_F11 */; break; + case 0x7b /*DOM_VK_F12*/: key = 12 /* GLUT_KEY_F12 */; break; + case 0x25 /*DOM_VK_LEFT*/: key = 100 /* GLUT_KEY_LEFT */; break; + case 0x26 /*DOM_VK_UP*/: key = 101 /* GLUT_KEY_UP */; break; + case 0x27 /*DOM_VK_RIGHT*/: key = 102 /* GLUT_KEY_RIGHT */; break; + case 0x28 /*DOM_VK_DOWN*/: key = 103 /* GLUT_KEY_DOWN */; break; + case 0x21 /*DOM_VK_PAGE_UP*/: key = 104 /* GLUT_KEY_PAGE_UP */; break; + case 0x22 /*DOM_VK_PAGE_DOWN*/: key = 105 /* GLUT_KEY_PAGE_DOWN */; break; + case 0x24 /*DOM_VK_HOME*/: key = 106 /* GLUT_KEY_HOME */; break; + case 0x23 /*DOM_VK_END*/: key = 107 /* GLUT_KEY_END */; break; + case 0x2d /*DOM_VK_INSERT*/: key = 108 /* GLUT_KEY_INSERT */; break; + default: return; + }; + if (key !== null) { + FUNCTION_TABLE[GLUT.keyboardFunc](key, GLUT.lastX, GLUT.lastY); + } + } + }, + }, + + glutInit__deps: ['$GLUT'], + glutInit: function(argcp, argv) { + // Ignore arguments + GLUT.initTime = Date.now(); + window.addEventListener("keydown", GLUT.onKeydown, true); + window.addEventListener("mousemove", GLUT.onMousemove, true); + }, + + glutInitWindowSize: function(width, height) { + Module['canvas'].width = width; + Module['canvas'].height = height; + }, + + glutGet: function(type) { + switch (type) { + case 700: /* GLUT_ELAPSED_TIME */ + var now = Date.now(); + return now - GLUT.initTime; + default: + throw "glutGet(" + type + ") not implemented yet"; + } + }, + + glutDisplayFunc: function(func) { + var RAF = window['setTimeout']; + if (window['requestAnimationFrame']) { + RAF = window['requestAnimationFrame']; + } else if (window['mozRequestAnimationFrame']) { + RAF = window['mozRequestAnimationFrame']; + } else if (window['webkitRequestAnimationFrame']) { + RAF = window['webkitRequestAnimationFrame']; + } else if (window['msRequestAnimationFrame']) { + RAF = window['msRequestAnimationFrame']; + } + RAF.apply(window, [function() { + if (GLUT.reshapeFunc) { + FUNCTION_TABLE[GLUT.reshapeFunc](Module['canvas'].width, + Module['canvas'].height); + } + if (GLUT.idleFunc) { + FUNCTION_TABLE[GLUT.idleFunc](); + } + FUNCTION_TABLE[func](); + _glutDisplayFunc(func); + }]); + }, + + glutIdleFunc: function(func) { + GLUT.idleFunc = func; + }, + + glutSpecialFunc: function(func) { + GLUT.keyboardFunc = func; + }, + + glutReshapeFunc: function(func) { + GLUT.reshapeFunc = func; + }, + + glutCreateWindow: function(name) { + try { + var ctx = Module.canvas.getContext('experimental-webgl'); + if (!ctx) throw 'Could not create canvas :('; + Module.ctx = ctx; + // Set the background of the canvas to black, because glut gives us a + // window which has a black background by default. + Module.canvas.style.backgroundColor = "black"; + } catch (e) { + Module.print('(canvas not available)'); + } + }, + + glutInitDisplayMode: function(mode) {}, + glutMainLoop: function() {}, + glutSwapBuffers: function() {}, + glutPostRedisplay: function() {}, +}; + mergeInto(LibraryManager.library, LibraryGL); +mergeInto(LibraryManager.library, LibraryGLUT); diff --git a/src/library_sdl.js b/src/library_sdl.js index ce26a106..d438fc23 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -176,6 +176,11 @@ mergeInto(LibraryManager.library, { try { var ctx = Module.canvas.getContext(useWebGL ? 'experimental-webgl' : '2d'); if (!ctx) throw 'Could not create canvas :('; + if (useWebGL) { + // Set the background of the WebGL canvas to black, because SDL gives us a + // window which has a black background by default. + Module.canvas.style.backgroundColor = "black"; + } return Module.ctx = ctx; } catch (e) { Module.print('(canvas not available)'); @@ -555,5 +560,15 @@ mergeInto(LibraryManager.library, { // SDL Mixer Mix_OpenAudio: function() { return -1 }, + + SDL_AddTimer: function(interval, callback, param) { + return window.setTimeout(function() { + FUNCTION_TABLE[callback](interval, param); + }, interval); + }, + SDL_RemoveTimer: function(id) { + window.clearTimeout(id); + return true; + }, }); diff --git a/src/preamble.js b/src/preamble.js index 94add7f4..d0391af5 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -490,16 +490,18 @@ function allocate(slab, types, allocator) { } Module['allocate'] = allocate; -function Pointer_stringify(ptr) { +function Pointer_stringify(ptr, /* optional */ length) { + var nullTerminated = typeof(length) == "undefined"; var ret = ""; var i = 0; var t; var nullByte = String.fromCharCode(0); while (1) { t = String.fromCharCode({{{ makeGetValue('ptr', 'i', 'i8', 0, 1) }}}); - if (t == nullByte) { break; } else {} + if (nullTerminated && t == nullByte) { break; } else {} ret += t; i += 1; + if (!nullTerminated && i == length) { break; } } return ret; } @@ -711,6 +713,20 @@ function Array_copy(ptr, num) { } Module['Array_copy'] = Array_copy; +#if USE_TYPED_ARRAYS +// Copies a list of num items on the HEAP into a +// JavaScript typed array. +function TypedArray_copy(ptr, num) { + // TODO: optimize this! + var arr = new Uint8Array(num); + for (var i = 0; i < num; ++i) { + arr[i] = {{{ makeGetValue('ptr', 'i', 'i8') }}}; + } + return arr.buffer; +} +Module['TypedArray_copy'] = TypedArray_copy; +#endif + function String_len(ptr) { var i = 0; while ({{{ makeGetValue('ptr', 'i', 'i8') }}}) i++; // Note: should be |!= 0|, technically. But this helps catch bugs with undefineds @@ -771,6 +787,25 @@ function intArrayToString(array) { } Module['intArrayToString'] = intArrayToString; +// Write a Javascript array to somewhere in the heap +function writeStringToMemory(string, buffer, dontAddNull) { + var i = 0; + while (i < string.length) { + var chr = string.charCodeAt(i); + if (chr > 0xFF) { +#if ASSERTIONS + assert(false, 'Character code ' + chr + ' (' + string[i] + ') at offset ' + i + ' not in 0x00-0xFF.'); +#endif + chr &= 0xFF; + } + {{{ makeSetValue('buffer', 'i', 'chr', 'i8') }}} + i = i + 1; + } + if (!dontAddNull) { + {{{ makeSetValue('buffer', 'i', '0', 'i8') }}} + } +} + var STRING_TABLE = []; {{{ unSign }}} diff --git a/src/shell.html b/src/shell.html index 6b6bbdad..69217b18 100644 --- a/src/shell.html +++ b/src/shell.html @@ -9,6 +9,11 @@ <div id='output'></div> <hr> <script type='text/javascript'> + /** + * TODO: Encapsulate this part in a reusable token such as + * EMSCRIPTEN_ENVIRONMENT so that we can share code + * between the default shell and custom ones. + */ // connect to canvas var Module = { print: (function() { diff --git a/system/include/GL/freeglut_std.h b/system/include/GL/freeglut_std.h new file mode 100644 index 00000000..ba1b7165 --- /dev/null +++ b/system/include/GL/freeglut_std.h @@ -0,0 +1,628 @@ +#ifndef __FREEGLUT_STD_H__ +#define __FREEGLUT_STD_H__ + +/* + * freeglut_std.h + * + * The GLUT-compatible part of the freeglut library include file + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, <olszta@sourceforge.net> + * Creation date: Thu Dec 2 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Under windows, we have to differentiate between static and dynamic libraries + */ +#ifdef _WIN32 +/* #pragma may not be supported by some compilers. + * Discussion by FreeGLUT developers suggests that + * Visual C++ specific code involving pragmas may + * need to move to a separate header. 24th Dec 2003 + */ + +/* Define FREEGLUT_LIB_PRAGMAS to 1 to include library + * pragmas or to 0 to exclude library pragmas. + * The default behavior depends on the compiler/platform. + */ +# ifndef FREEGLUT_LIB_PRAGMAS +# if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(_WIN32_WCE) +# define FREEGLUT_LIB_PRAGMAS 1 +# else +# define FREEGLUT_LIB_PRAGMAS 0 +# endif +# endif + +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include <windows.h> + +/* Windows static library */ +# ifdef FREEGLUT_STATIC + +# define FGAPI +# define FGAPIENTRY + + /* Link with Win32 static freeglut lib */ +# if FREEGLUT_LIB_PRAGMAS +# pragma comment (lib, "freeglut_static.lib") +# endif + +/* Windows shared library (DLL) */ +# else + +# define FGAPIENTRY __stdcall +# if defined(FREEGLUT_EXPORTS) +# define FGAPI __declspec(dllexport) +# else +# define FGAPI __declspec(dllimport) + + /* Link with Win32 shared freeglut lib */ +# if FREEGLUT_LIB_PRAGMAS +# pragma comment (lib, "freeglut.lib") +# endif + +# endif + +# endif + +/* Drag in other Windows libraries as required by FreeGLUT */ +# if FREEGLUT_LIB_PRAGMAS +# pragma comment (lib, "glu32.lib") /* link OpenGL Utility lib */ +# pragma comment (lib, "opengl32.lib") /* link Microsoft OpenGL lib */ +# pragma comment (lib, "gdi32.lib") /* link Windows GDI lib */ +# pragma comment (lib, "winmm.lib") /* link Windows MultiMedia lib */ +# pragma comment (lib, "user32.lib") /* link Windows user lib */ +# endif + +#else + +/* Non-Windows definition of FGAPI and FGAPIENTRY */ +# define FGAPI +# define FGAPIENTRY + +#endif + +/* + * The freeglut and GLUT API versions + */ +#define FREEGLUT 1 +#define GLUT_API_VERSION 4 +#define FREEGLUT_VERSION_2_0 1 +#define GLUT_XLIB_IMPLEMENTATION 13 + +/* + * Always include OpenGL and GLU headers + */ +#include <GL/gl.h> +#include <GL/glu.h> + +/* + * GLUT API macro definitions -- the special key codes: + */ +#define GLUT_KEY_F1 0x0001 +#define GLUT_KEY_F2 0x0002 +#define GLUT_KEY_F3 0x0003 +#define GLUT_KEY_F4 0x0004 +#define GLUT_KEY_F5 0x0005 +#define GLUT_KEY_F6 0x0006 +#define GLUT_KEY_F7 0x0007 +#define GLUT_KEY_F8 0x0008 +#define GLUT_KEY_F9 0x0009 +#define GLUT_KEY_F10 0x000A +#define GLUT_KEY_F11 0x000B +#define GLUT_KEY_F12 0x000C +#define GLUT_KEY_LEFT 0x0064 +#define GLUT_KEY_UP 0x0065 +#define GLUT_KEY_RIGHT 0x0066 +#define GLUT_KEY_DOWN 0x0067 +#define GLUT_KEY_PAGE_UP 0x0068 +#define GLUT_KEY_PAGE_DOWN 0x0069 +#define GLUT_KEY_HOME 0x006A +#define GLUT_KEY_END 0x006B +#define GLUT_KEY_INSERT 0x006C + +/* + * GLUT API macro definitions -- mouse state definitions + */ +#define GLUT_LEFT_BUTTON 0x0000 +#define GLUT_MIDDLE_BUTTON 0x0001 +#define GLUT_RIGHT_BUTTON 0x0002 +#define GLUT_DOWN 0x0000 +#define GLUT_UP 0x0001 +#define GLUT_LEFT 0x0000 +#define GLUT_ENTERED 0x0001 + +/* + * GLUT API macro definitions -- the display mode definitions + */ +#define GLUT_RGB 0x0000 +#define GLUT_RGBA 0x0000 +#define GLUT_INDEX 0x0001 +#define GLUT_SINGLE 0x0000 +#define GLUT_DOUBLE 0x0002 +#define GLUT_ACCUM 0x0004 +#define GLUT_ALPHA 0x0008 +#define GLUT_DEPTH 0x0010 +#define GLUT_STENCIL 0x0020 +#define GLUT_MULTISAMPLE 0x0080 +#define GLUT_STEREO 0x0100 +#define GLUT_LUMINANCE 0x0200 + +/* + * GLUT API macro definitions -- windows and menu related definitions + */ +#define GLUT_MENU_NOT_IN_USE 0x0000 +#define GLUT_MENU_IN_USE 0x0001 +#define GLUT_NOT_VISIBLE 0x0000 +#define GLUT_VISIBLE 0x0001 +#define GLUT_HIDDEN 0x0000 +#define GLUT_FULLY_RETAINED 0x0001 +#define GLUT_PARTIALLY_RETAINED 0x0002 +#define GLUT_FULLY_COVERED 0x0003 + +/* + * GLUT API macro definitions -- fonts definitions + * + * Steve Baker suggested to make it binary compatible with GLUT: + */ +#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WATCOMC__) +# define GLUT_STROKE_ROMAN ((void *)0x0000) +# define GLUT_STROKE_MONO_ROMAN ((void *)0x0001) +# define GLUT_BITMAP_9_BY_15 ((void *)0x0002) +# define GLUT_BITMAP_8_BY_13 ((void *)0x0003) +# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *)0x0004) +# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *)0x0005) +# define GLUT_BITMAP_HELVETICA_10 ((void *)0x0006) +# define GLUT_BITMAP_HELVETICA_12 ((void *)0x0007) +# define GLUT_BITMAP_HELVETICA_18 ((void *)0x0008) +#else + /* + * I don't really know if it's a good idea... But here it goes: + */ + extern void* glutStrokeRoman; + extern void* glutStrokeMonoRoman; + extern void* glutBitmap9By15; + extern void* glutBitmap8By13; + extern void* glutBitmapTimesRoman10; + extern void* glutBitmapTimesRoman24; + extern void* glutBitmapHelvetica10; + extern void* glutBitmapHelvetica12; + extern void* glutBitmapHelvetica18; + + /* + * Those pointers will be used by following definitions: + */ +# define GLUT_STROKE_ROMAN ((void *) &glutStrokeRoman) +# define GLUT_STROKE_MONO_ROMAN ((void *) &glutStrokeMonoRoman) +# define GLUT_BITMAP_9_BY_15 ((void *) &glutBitmap9By15) +# define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13) +# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *) &glutBitmapTimesRoman10) +# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *) &glutBitmapTimesRoman24) +# define GLUT_BITMAP_HELVETICA_10 ((void *) &glutBitmapHelvetica10) +# define GLUT_BITMAP_HELVETICA_12 ((void *) &glutBitmapHelvetica12) +# define GLUT_BITMAP_HELVETICA_18 ((void *) &glutBitmapHelvetica18) +#endif + +/* + * GLUT API macro definitions -- the glutGet parameters + */ +#define GLUT_WINDOW_X 0x0064 +#define GLUT_WINDOW_Y 0x0065 +#define GLUT_WINDOW_WIDTH 0x0066 +#define GLUT_WINDOW_HEIGHT 0x0067 +#define GLUT_WINDOW_BUFFER_SIZE 0x0068 +#define GLUT_WINDOW_STENCIL_SIZE 0x0069 +#define GLUT_WINDOW_DEPTH_SIZE 0x006A +#define GLUT_WINDOW_RED_SIZE 0x006B +#define GLUT_WINDOW_GREEN_SIZE 0x006C +#define GLUT_WINDOW_BLUE_SIZE 0x006D +#define GLUT_WINDOW_ALPHA_SIZE 0x006E +#define GLUT_WINDOW_ACCUM_RED_SIZE 0x006F +#define GLUT_WINDOW_ACCUM_GREEN_SIZE 0x0070 +#define GLUT_WINDOW_ACCUM_BLUE_SIZE 0x0071 +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 0x0072 +#define GLUT_WINDOW_DOUBLEBUFFER 0x0073 +#define GLUT_WINDOW_RGBA 0x0074 +#define GLUT_WINDOW_PARENT 0x0075 +#define GLUT_WINDOW_NUM_CHILDREN 0x0076 +#define GLUT_WINDOW_COLORMAP_SIZE 0x0077 +#define GLUT_WINDOW_NUM_SAMPLES 0x0078 +#define GLUT_WINDOW_STEREO 0x0079 +#define GLUT_WINDOW_CURSOR 0x007A + +#define GLUT_SCREEN_WIDTH 0x00C8 +#define GLUT_SCREEN_HEIGHT 0x00C9 +#define GLUT_SCREEN_WIDTH_MM 0x00CA +#define GLUT_SCREEN_HEIGHT_MM 0x00CB +#define GLUT_MENU_NUM_ITEMS 0x012C +#define GLUT_DISPLAY_MODE_POSSIBLE 0x0190 +#define GLUT_INIT_WINDOW_X 0x01F4 +#define GLUT_INIT_WINDOW_Y 0x01F5 +#define GLUT_INIT_WINDOW_WIDTH 0x01F6 +#define GLUT_INIT_WINDOW_HEIGHT 0x01F7 +#define GLUT_INIT_DISPLAY_MODE 0x01F8 +#define GLUT_ELAPSED_TIME 0x02BC +#define GLUT_WINDOW_FORMAT_ID 0x007B + +/* + * GLUT API macro definitions -- the glutDeviceGet parameters + */ +#define GLUT_HAS_KEYBOARD 0x0258 +#define GLUT_HAS_MOUSE 0x0259 +#define GLUT_HAS_SPACEBALL 0x025A +#define GLUT_HAS_DIAL_AND_BUTTON_BOX 0x025B +#define GLUT_HAS_TABLET 0x025C +#define GLUT_NUM_MOUSE_BUTTONS 0x025D +#define GLUT_NUM_SPACEBALL_BUTTONS 0x025E +#define GLUT_NUM_BUTTON_BOX_BUTTONS 0x025F +#define GLUT_NUM_DIALS 0x0260 +#define GLUT_NUM_TABLET_BUTTONS 0x0261 +#define GLUT_DEVICE_IGNORE_KEY_REPEAT 0x0262 +#define GLUT_DEVICE_KEY_REPEAT 0x0263 +#define GLUT_HAS_JOYSTICK 0x0264 +#define GLUT_OWNS_JOYSTICK 0x0265 +#define GLUT_JOYSTICK_BUTTONS 0x0266 +#define GLUT_JOYSTICK_AXES 0x0267 +#define GLUT_JOYSTICK_POLL_RATE 0x0268 + +/* + * GLUT API macro definitions -- the glutLayerGet parameters + */ +#define GLUT_OVERLAY_POSSIBLE 0x0320 +#define GLUT_LAYER_IN_USE 0x0321 +#define GLUT_HAS_OVERLAY 0x0322 +#define GLUT_TRANSPARENT_INDEX 0x0323 +#define GLUT_NORMAL_DAMAGED 0x0324 +#define GLUT_OVERLAY_DAMAGED 0x0325 + +/* + * GLUT API macro definitions -- the glutVideoResizeGet parameters + */ +#define GLUT_VIDEO_RESIZE_POSSIBLE 0x0384 +#define GLUT_VIDEO_RESIZE_IN_USE 0x0385 +#define GLUT_VIDEO_RESIZE_X_DELTA 0x0386 +#define GLUT_VIDEO_RESIZE_Y_DELTA 0x0387 +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 0x0388 +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 0x0389 +#define GLUT_VIDEO_RESIZE_X 0x038A +#define GLUT_VIDEO_RESIZE_Y 0x038B +#define GLUT_VIDEO_RESIZE_WIDTH 0x038C +#define GLUT_VIDEO_RESIZE_HEIGHT 0x038D + +/* + * GLUT API macro definitions -- the glutUseLayer parameters + */ +#define GLUT_NORMAL 0x0000 +#define GLUT_OVERLAY 0x0001 + +/* + * GLUT API macro definitions -- the glutGetModifiers parameters + */ +#define GLUT_ACTIVE_SHIFT 0x0001 +#define GLUT_ACTIVE_CTRL 0x0002 +#define GLUT_ACTIVE_ALT 0x0004 + +/* + * GLUT API macro definitions -- the glutSetCursor parameters + */ +#define GLUT_CURSOR_RIGHT_ARROW 0x0000 +#define GLUT_CURSOR_LEFT_ARROW 0x0001 +#define GLUT_CURSOR_INFO 0x0002 +#define GLUT_CURSOR_DESTROY 0x0003 +#define GLUT_CURSOR_HELP 0x0004 +#define GLUT_CURSOR_CYCLE 0x0005 +#define GLUT_CURSOR_SPRAY 0x0006 +#define GLUT_CURSOR_WAIT 0x0007 +#define GLUT_CURSOR_TEXT 0x0008 +#define GLUT_CURSOR_CROSSHAIR 0x0009 +#define GLUT_CURSOR_UP_DOWN 0x000A +#define GLUT_CURSOR_LEFT_RIGHT 0x000B +#define GLUT_CURSOR_TOP_SIDE 0x000C +#define GLUT_CURSOR_BOTTOM_SIDE 0x000D +#define GLUT_CURSOR_LEFT_SIDE 0x000E +#define GLUT_CURSOR_RIGHT_SIDE 0x000F +#define GLUT_CURSOR_TOP_LEFT_CORNER 0x0010 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 0x0011 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 0x0012 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 0x0013 +#define GLUT_CURSOR_INHERIT 0x0064 +#define GLUT_CURSOR_NONE 0x0065 +#define GLUT_CURSOR_FULL_CROSSHAIR 0x0066 + +/* + * GLUT API macro definitions -- RGB color component specification definitions + */ +#define GLUT_RED 0x0000 +#define GLUT_GREEN 0x0001 +#define GLUT_BLUE 0x0002 + +/* + * GLUT API macro definitions -- additional keyboard and joystick definitions + */ +#define GLUT_KEY_REPEAT_OFF 0x0000 +#define GLUT_KEY_REPEAT_ON 0x0001 +#define GLUT_KEY_REPEAT_DEFAULT 0x0002 + +#define GLUT_JOYSTICK_BUTTON_A 0x0001 +#define GLUT_JOYSTICK_BUTTON_B 0x0002 +#define GLUT_JOYSTICK_BUTTON_C 0x0004 +#define GLUT_JOYSTICK_BUTTON_D 0x0008 + +/* + * GLUT API macro definitions -- game mode definitions + */ +#define GLUT_GAME_MODE_ACTIVE 0x0000 +#define GLUT_GAME_MODE_POSSIBLE 0x0001 +#define GLUT_GAME_MODE_WIDTH 0x0002 +#define GLUT_GAME_MODE_HEIGHT 0x0003 +#define GLUT_GAME_MODE_PIXEL_DEPTH 0x0004 +#define GLUT_GAME_MODE_REFRESH_RATE 0x0005 +#define GLUT_GAME_MODE_DISPLAY_CHANGED 0x0006 + +/* + * Initialization functions, see fglut_init.c + */ +FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv ); +FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y ); +FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height ); +FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode ); +FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode ); + +/* + * Process loop function, see freeglut_main.c + */ +FGAPI void FGAPIENTRY glutMainLoop( void ); + +/* + * Window management functions, see freeglut_window.c + */ +FGAPI int FGAPIENTRY glutCreateWindow( const char* title ); +FGAPI int FGAPIENTRY glutCreateSubWindow( int window, int x, int y, int width, int height ); +FGAPI void FGAPIENTRY glutDestroyWindow( int window ); +FGAPI void FGAPIENTRY glutSetWindow( int window ); +FGAPI int FGAPIENTRY glutGetWindow( void ); +FGAPI void FGAPIENTRY glutSetWindowTitle( const char* title ); +FGAPI void FGAPIENTRY glutSetIconTitle( const char* title ); +FGAPI void FGAPIENTRY glutReshapeWindow( int width, int height ); +FGAPI void FGAPIENTRY glutPositionWindow( int x, int y ); +FGAPI void FGAPIENTRY glutShowWindow( void ); +FGAPI void FGAPIENTRY glutHideWindow( void ); +FGAPI void FGAPIENTRY glutIconifyWindow( void ); +FGAPI void FGAPIENTRY glutPushWindow( void ); +FGAPI void FGAPIENTRY glutPopWindow( void ); +FGAPI void FGAPIENTRY glutFullScreen( void ); + +/* + * Display-connected functions, see freeglut_display.c + */ +FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window ); +FGAPI void FGAPIENTRY glutPostRedisplay( void ); +FGAPI void FGAPIENTRY glutSwapBuffers( void ); + +/* + * Mouse cursor functions, see freeglut_cursor.c + */ +FGAPI void FGAPIENTRY glutWarpPointer( int x, int y ); +FGAPI void FGAPIENTRY glutSetCursor( int cursor ); + +/* + * Overlay stuff, see freeglut_overlay.c + */ +FGAPI void FGAPIENTRY glutEstablishOverlay( void ); +FGAPI void FGAPIENTRY glutRemoveOverlay( void ); +FGAPI void FGAPIENTRY glutUseLayer( GLenum layer ); +FGAPI void FGAPIENTRY glutPostOverlayRedisplay( void ); +FGAPI void FGAPIENTRY glutPostWindowOverlayRedisplay( int window ); +FGAPI void FGAPIENTRY glutShowOverlay( void ); +FGAPI void FGAPIENTRY glutHideOverlay( void ); + +/* + * Menu stuff, see freeglut_menu.c + */ +FGAPI int FGAPIENTRY glutCreateMenu( void (* callback)( int menu ) ); +FGAPI void FGAPIENTRY glutDestroyMenu( int menu ); +FGAPI int FGAPIENTRY glutGetMenu( void ); +FGAPI void FGAPIENTRY glutSetMenu( int menu ); +FGAPI void FGAPIENTRY glutAddMenuEntry( const char* label, int value ); +FGAPI void FGAPIENTRY glutAddSubMenu( const char* label, int subMenu ); +FGAPI void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value ); +FGAPI void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int value ); +FGAPI void FGAPIENTRY glutRemoveMenuItem( int item ); +FGAPI void FGAPIENTRY glutAttachMenu( int button ); +FGAPI void FGAPIENTRY glutDetachMenu( int button ); + +/* + * Global callback functions, see freeglut_callbacks.c + */ +FGAPI void FGAPIENTRY glutTimerFunc( unsigned int time, void (* callback)( int ), int value ); +FGAPI void FGAPIENTRY glutIdleFunc( void (* callback)( void ) ); + +/* + * Window-specific callback functions, see freeglut_callbacks.c + */ +FGAPI void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) ); +FGAPI void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) ); +FGAPI void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) ); +FGAPI void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) ); +FGAPI void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutEntryFunc( void (* callback)( int ) ); + +FGAPI void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) ); +FGAPI void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval ); +FGAPI void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) ); +FGAPI void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) ); +FGAPI void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) ); + +FGAPI void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) ); + +/* + * State setting and retrieval functions, see freeglut_state.c + */ +FGAPI int FGAPIENTRY glutGet( GLenum query ); +FGAPI int FGAPIENTRY glutDeviceGet( GLenum query ); +FGAPI int FGAPIENTRY glutGetModifiers( void ); +FGAPI int FGAPIENTRY glutLayerGet( GLenum query ); + +/* + * Font stuff, see freeglut_font.c + */ +FGAPI void FGAPIENTRY glutBitmapCharacter( void* font, int character ); +FGAPI int FGAPIENTRY glutBitmapWidth( void* font, int character ); +FGAPI void FGAPIENTRY glutStrokeCharacter( void* font, int character ); +FGAPI int FGAPIENTRY glutStrokeWidth( void* font, int character ); +FGAPI int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string ); +FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string ); + +/* + * Geometry functions, see freeglut_geometry.c + */ +FGAPI void FGAPIENTRY glutWireCube( GLdouble size ); +FGAPI void FGAPIENTRY glutSolidCube( GLdouble size ); +FGAPI void FGAPIENTRY glutWireSphere( GLdouble radius, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutSolidSphere( GLdouble radius, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks ); + +FGAPI void FGAPIENTRY glutWireTorus( GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings ); +FGAPI void FGAPIENTRY glutSolidTorus( GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings ); +FGAPI void FGAPIENTRY glutWireDodecahedron( void ); +FGAPI void FGAPIENTRY glutSolidDodecahedron( void ); +FGAPI void FGAPIENTRY glutWireOctahedron( void ); +FGAPI void FGAPIENTRY glutSolidOctahedron( void ); +FGAPI void FGAPIENTRY glutWireTetrahedron( void ); +FGAPI void FGAPIENTRY glutSolidTetrahedron( void ); +FGAPI void FGAPIENTRY glutWireIcosahedron( void ); +FGAPI void FGAPIENTRY glutSolidIcosahedron( void ); + +/* + * Teapot rendering functions, found in freeglut_teapot.c + */ +FGAPI void FGAPIENTRY glutWireTeapot( GLdouble size ); +FGAPI void FGAPIENTRY glutSolidTeapot( GLdouble size ); + +/* + * Game mode functions, see freeglut_gamemode.c + */ +FGAPI void FGAPIENTRY glutGameModeString( const char* string ); +FGAPI int FGAPIENTRY glutEnterGameMode( void ); +FGAPI void FGAPIENTRY glutLeaveGameMode( void ); +FGAPI int FGAPIENTRY glutGameModeGet( GLenum query ); + +/* + * Video resize functions, see freeglut_videoresize.c + */ +FGAPI int FGAPIENTRY glutVideoResizeGet( GLenum query ); +FGAPI void FGAPIENTRY glutSetupVideoResizing( void ); +FGAPI void FGAPIENTRY glutStopVideoResizing( void ); +FGAPI void FGAPIENTRY glutVideoResize( int x, int y, int width, int height ); +FGAPI void FGAPIENTRY glutVideoPan( int x, int y, int width, int height ); + +/* + * Colormap functions, see freeglut_misc.c + */ +FGAPI void FGAPIENTRY glutSetColor( int color, GLfloat red, GLfloat green, GLfloat blue ); +FGAPI GLfloat FGAPIENTRY glutGetColor( int color, int component ); +FGAPI void FGAPIENTRY glutCopyColormap( int window ); + +/* + * Misc keyboard and joystick functions, see freeglut_misc.c + */ +FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore ); +FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode ); +FGAPI void FGAPIENTRY glutForceJoystickFunc( void ); + +/* + * Misc functions, see freeglut_misc.c + */ +FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension ); +FGAPI void FGAPIENTRY glutReportErrors( void ); + +/* Comment from glut.h of classic GLUT: + + Win32 has an annoying issue where there are multiple C run-time + libraries (CRTs). If the executable is linked with a different CRT + from the GLUT DLL, the GLUT DLL will not share the same CRT static + data seen by the executable. In particular, atexit callbacks registered + in the executable will not be called if GLUT calls its (different) + exit routine). GLUT is typically built with the + "/MD" option (the CRT with multithreading DLL support), but the Visual + C++ linker default is "/ML" (the single threaded CRT). + + One workaround to this issue is requiring users to always link with + the same CRT as GLUT is compiled with. That requires users supply a + non-standard option. GLUT 3.7 has its own built-in workaround where + the executable's "exit" function pointer is covertly passed to GLUT. + GLUT then calls the executable's exit function pointer to ensure that + any "atexit" calls registered by the application are called if GLUT + needs to exit. + + Note that the __glut*WithExit routines should NEVER be called directly. + To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */ + +/* to get the prototype for exit() */ +#include <stdlib.h> + +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__) +FGAPI void FGAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); +FGAPI int FGAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); +FGAPI int FGAPIENTRY __glutCreateMenuWithExit(void (* func)(int), void (__cdecl *exitfunc)(int)); +#ifndef FREEGLUT_BUILDING_LIB +#if defined(__GNUC__) +#define FGUNUSED __attribute__((unused)) +#else +#define FGUNUSED +#endif +static void FGAPIENTRY FGUNUSED glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } +#define glutInit glutInit_ATEXIT_HACK +static int FGAPIENTRY FGUNUSED glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } +#define glutCreateWindow glutCreateWindow_ATEXIT_HACK +static int FGAPIENTRY FGUNUSED glutCreateMenu_ATEXIT_HACK(void (* func)(int)) { return __glutCreateMenuWithExit(func, exit); } +#define glutCreateMenu glutCreateMenu_ATEXIT_HACK +#endif +#endif + +#ifdef __cplusplus + } +#endif + +/*** END OF FILE ***/ + +#endif /* __FREEGLUT_STD_H__ */ + diff --git a/system/include/GL/glut.h b/system/include/GL/glut.h new file mode 100644 index 00000000..6191f77b --- /dev/null +++ b/system/include/GL/glut.h @@ -0,0 +1,21 @@ +#ifndef __GLUT_H__ +#define __GLUT_H__ + +/* + * glut.h + * + * The freeglut library include file + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "freeglut_std.h" + +/*** END OF FILE ***/ + +#endif /* __GLUT_H__ */ diff --git a/system/include/GLES2/gl2.h b/system/include/GLES2/gl2.h new file mode 100644 index 00000000..e1d3b87c --- /dev/null +++ b/system/include/GLES2/gl2.h @@ -0,0 +1,621 @@ +#ifndef __gl2_h_ +#define __gl2_h_ + +/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */ + +#include <GLES2/gl2platform.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +typedef void GLvoid; +typedef char GLchar; +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef khronos_int8_t GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; + +/* GL types for handling large vertex buffer objects */ +typedef khronos_intptr_t GLintptr; +typedef khronos_ssize_t GLsizeiptr; + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_2_0 1 + +/* ClearBufferMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 + +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 + +/* AlphaFunction (not supported in ES20) */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ + +/* BlendEquationSeparate */ +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* BlendSubtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* Separate Blend Functions */ +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* Buffer Objects */ +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 + +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 + +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 + +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 + +/* CullFaceMode */ +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* EnableCap */ +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 + +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetPName */ +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +/* GL_SCISSOR_TEST */ +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +/* GL_POLYGON_OFFSET_FILL */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ + +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C + +/* PixelFormat */ +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +/* PixelType */ +/* GL_UNSIGNED_BYTE */ +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 + +/* Shaders */ +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D + +/* StencilFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +/* TextureTarget */ +/* GL_TEXTURE_2D */ +#define GL_TEXTURE 0x1702 + +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +/* TextureUnit */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 + +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 + +/* Uniform Types */ +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 + +/* Vertex Arrays */ +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + +/* Read Format */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + +/* Shader Source */ +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA + +/* Shader Binary */ +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + +/* Shader Precision-Specified Types */ +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + +/* Framebuffer Object. */ +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 + +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 + +#define GL_NONE 0 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +/*------------------------------------------------------------------------- + * GL core functions. + *-----------------------------------------------------------------------*/ + +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); +GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar** string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2_h_ */ diff --git a/system/include/GLES2/gl2platform.h b/system/include/GLES2/gl2platform.h new file mode 100644 index 00000000..c9fa3c4d --- /dev/null +++ b/system/include/GLES2/gl2platform.h @@ -0,0 +1,30 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +#include <KHR/khrplatform.h> + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl2platform_h_ */ diff --git a/system/include/KHR/khrplatform.h b/system/include/KHR/khrplatform.h new file mode 100644 index 00000000..44795394 --- /dev/null +++ b/system/include/KHR/khrplatform.h @@ -0,0 +1,277 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include <KHR/khrplatform.h> + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# if defined(KHRONOS_DLL_EXPORTS) +# define KHRONOS_APICALL __declspec(dllexport) +# else +# define KHRONOS_APICALL __declspec(dllimport) +# endif +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#elif (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303) \ + || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +/* KHRONOS_APIATTRIBUTES is not used by the client API headers yet */ +# define KHRONOS_APICALL __attribute__((visibility("default"))) +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using <stdint.h> + */ +#include <stdint.h> +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using <inttypes.h> + */ +#include <inttypes.h> +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include <stdint.h> +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/tests/hello_world_gles.c b/tests/hello_world_gles.c new file mode 100644 index 00000000..4f2cb45c --- /dev/null +++ b/tests/hello_world_gles.c @@ -0,0 +1,729 @@ +/* + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Ported to GLES2. + * Kristian Høgsberg <krh@bitplanet.net> + * May 3, 2010 + * + * Improve GLES2 port: + * * Refactor gear drawing. + * * Use correct normals for surfaces. + * * Improve shader. + * * Use perspective projection transformation. + * * Add FPS count. + * * Add comments. + * Alexandros Frantzis <alexandros.frantzis@linaro.org> + * Jul 13, 2010 + */ + +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES + +#define _GNU_SOURCE + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> +#include <GL/gl.h> +#include <GL/glut.h> + +#ifndef HAVE_BUILTIN_SINCOS +#include "sincos.h" +#endif + +#define STRIPS_PER_TOOTH 7 +#define VERTICES_PER_TOOTH 34 +#define GEAR_VERTEX_STRIDE 6 + +/** + * Struct describing the vertices in triangle strip + */ +struct vertex_strip { + /** The first vertex in the strip */ + GLint first; + /** The number of consecutive vertices in the strip after the first */ + GLint count; +}; + +/* Each vertex consist of GEAR_VERTEX_STRIDE GLfloat attributes */ +typedef GLfloat GearVertex[GEAR_VERTEX_STRIDE]; + +/** + * Struct representing a gear. + */ +struct gear { + /** The array of vertices comprising the gear */ + GearVertex *vertices; + /** The number of vertices comprising the gear */ + int nvertices; + /** The array of triangle strips comprising the gear */ + struct vertex_strip *strips; + /** The number of triangle strips comprising the gear */ + int nstrips; + /** The Vertex Buffer Object holding the vertices in the graphics card */ + GLuint vbo; +}; + +/** The view rotation [x, y, z] */ +static GLfloat view_rot[3] = { 20.0, 30.0, 0.0 }; +/** The gears */ +static struct gear *gear1, *gear2, *gear3; +/** The current gear rotation angle */ +static GLfloat angle = 0.0; +/** The location of the shader uniforms */ +static GLuint ModelViewProjectionMatrix_location, + NormalMatrix_location, + LightSourcePosition_location, + MaterialColor_location; +/** The projection matrix */ +static GLfloat ProjectionMatrix[16]; +/** The direction of the directional light for the scene */ +static const GLfloat LightSourcePosition[4] = { 5.0, 5.0, 10.0, 1.0}; + +/** + * Fills a gear vertex. + * + * @param v the vertex to fill + * @param x the x coordinate + * @param y the y coordinate + * @param z the z coortinate + * @param n pointer to the normal table + * + * @return the operation error code + */ +static GearVertex * +vert(GearVertex *v, GLfloat x, GLfloat y, GLfloat z, GLfloat n[3]) +{ + v[0][0] = x; + v[0][1] = y; + v[0][2] = z; + v[0][3] = n[0]; + v[0][4] = n[1]; + v[0][5] = n[2]; + + return v + 1; +} + +/** + * Create a gear wheel. + * + * @param inner_radius radius of hole at center + * @param outer_radius radius at center of teeth + * @param width width of gear + * @param teeth number of teeth + * @param tooth_depth depth of tooth + * + * @return pointer to the constructed struct gear + */ +static struct gear * +create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, + GLint teeth, GLfloat tooth_depth) +{ + GLfloat r0, r1, r2; + GLfloat da; + GearVertex *v; + struct gear *gear; + double s[5], c[5]; + GLfloat normal[3]; + int cur_strip = 0; + int i; + + /* Allocate memory for the gear */ + gear = malloc(sizeof *gear); + if (gear == NULL) + return NULL; + + /* Calculate the radii used in the gear */ + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.0; + r2 = outer_radius + tooth_depth / 2.0; + + da = 2.0 * M_PI / teeth / 4.0; + + /* Allocate memory for the triangle strip information */ + gear->nstrips = STRIPS_PER_TOOTH * teeth; + gear->strips = calloc(gear->nstrips, sizeof (*gear->strips)); + + /* Allocate memory for the vertices */ + gear->vertices = calloc(VERTICES_PER_TOOTH * teeth, sizeof(*gear->vertices)); + v = gear->vertices; + + for (i = 0; i < teeth; i++) { + /* Calculate needed sin/cos for varius angles */ + sincos(i * 2.0 * M_PI / teeth, &s[0], &c[0]); + sincos(i * 2.0 * M_PI / teeth + da, &s[1], &c[1]); + sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]); + sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]); + sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]); + + /* A set of macros for making the creation of the gears easier */ +#define GEAR_POINT(r, da) { (r) * c[(da)], (r) * s[(da)] } +#define SET_NORMAL(x, y, z) do { \ + normal[0] = (x); normal[1] = (y); normal[2] = (z); \ +} while(0) + +#define GEAR_VERT(v, point, sign) vert((v), p[(point)].x, p[(point)].y, (sign) * width * 0.5, normal) + +#define START_STRIP do { \ + gear->strips[cur_strip].first = v - gear->vertices; \ +} while(0); + +#define END_STRIP do { \ + int _tmp = (v - gear->vertices); \ + gear->strips[cur_strip].count = _tmp - gear->strips[cur_strip].first; \ + cur_strip++; \ +} while (0) + +#define QUAD_WITH_NORMAL(p1, p2) do { \ + SET_NORMAL((p[(p1)].y - p[(p2)].y), -(p[(p1)].x - p[(p2)].x), 0); \ + v = GEAR_VERT(v, (p1), -1); \ + v = GEAR_VERT(v, (p1), 1); \ + v = GEAR_VERT(v, (p2), -1); \ + v = GEAR_VERT(v, (p2), 1); \ +} while(0) + + struct point { + GLfloat x; + GLfloat y; + }; + + /* Create the 7 points (only x,y coords) used to draw a tooth */ + struct point p[7] = { + GEAR_POINT(r2, 1), // 0 + GEAR_POINT(r2, 2), // 1 + GEAR_POINT(r1, 0), // 2 + GEAR_POINT(r1, 3), // 3 + GEAR_POINT(r0, 0), // 4 + GEAR_POINT(r1, 4), // 5 + GEAR_POINT(r0, 4), // 6 + }; + + /* Front face */ + START_STRIP; + SET_NORMAL(0, 0, 1.0); + v = GEAR_VERT(v, 0, +1); + v = GEAR_VERT(v, 1, +1); + v = GEAR_VERT(v, 2, +1); + v = GEAR_VERT(v, 3, +1); + v = GEAR_VERT(v, 4, +1); + v = GEAR_VERT(v, 5, +1); + v = GEAR_VERT(v, 6, +1); + END_STRIP; + + /* Inner face */ + START_STRIP; + QUAD_WITH_NORMAL(4, 6); + END_STRIP; + + /* Back face */ + START_STRIP; + SET_NORMAL(0, 0, -1.0); + v = GEAR_VERT(v, 6, -1); + v = GEAR_VERT(v, 5, -1); + v = GEAR_VERT(v, 4, -1); + v = GEAR_VERT(v, 3, -1); + v = GEAR_VERT(v, 2, -1); + v = GEAR_VERT(v, 1, -1); + v = GEAR_VERT(v, 0, -1); + END_STRIP; + + /* Outer face */ + START_STRIP; + QUAD_WITH_NORMAL(0, 2); + END_STRIP; + + START_STRIP; + QUAD_WITH_NORMAL(1, 0); + END_STRIP; + + START_STRIP; + QUAD_WITH_NORMAL(3, 1); + END_STRIP; + + START_STRIP; + QUAD_WITH_NORMAL(5, 3); + END_STRIP; + } + + gear->nvertices = (v - gear->vertices); + + /* Store the vertices in a vertex buffer object (VBO) */ + glGenBuffers(1, &gear->vbo); + glBindBuffer(GL_ARRAY_BUFFER, gear->vbo); + glBufferData(GL_ARRAY_BUFFER, gear->nvertices * sizeof(GearVertex), + gear->vertices, GL_STATIC_DRAW); + + return gear; +} + +/** + * Multiplies two 4x4 matrices. + * + * The result is stored in matrix m. + * + * @param m the first matrix to multiply + * @param n the second matrix to multiply + */ +static void +multiply(GLfloat *m, const GLfloat *n) +{ + GLfloat tmp[16]; + const GLfloat *row, *column; + div_t d; + int i, j; + + for (i = 0; i < 16; i++) { + tmp[i] = 0; + d = div(i, 4); + row = n + d.quot * 4; + column = m + d.rem; + for (j = 0; j < 4; j++) + tmp[i] += row[j] * column[j * 4]; + } + memcpy(m, &tmp, sizeof tmp); +} + +/** + * Rotates a 4x4 matrix. + * + * @param[in,out] m the matrix to rotate + * @param angle the angle to rotate + * @param x the x component of the direction to rotate to + * @param y the y component of the direction to rotate to + * @param z the z component of the direction to rotate to + */ +static void +rotate(GLfloat *m, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) +{ + double s, c; + + sincos(angle, &s, &c); + GLfloat r[16] = { + x * x * (1 - c) + c, y * x * (1 - c) + z * s, x * z * (1 - c) - y * s, 0, + x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0, + x * z * (1 - c) + y * s, y * z * (1 - c) - x * s, z * z * (1 - c) + c, 0, + 0, 0, 0, 1 + }; + + multiply(m, r); +} + + +/** + * Translates a 4x4 matrix. + * + * @param[in,out] m the matrix to translate + * @param x the x component of the direction to translate to + * @param y the y component of the direction to translate to + * @param z the z component of the direction to translate to + */ +static void +translate(GLfloat *m, GLfloat x, GLfloat y, GLfloat z) +{ + GLfloat t[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 }; + + multiply(m, t); +} + +/** + * Creates an identity 4x4 matrix. + * + * @param m the matrix make an identity matrix + */ +static void +identity(GLfloat *m) +{ + GLfloat t[16] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + }; + + memcpy(m, t, sizeof(t)); +} + +/** + * Transposes a 4x4 matrix. + * + * @param m the matrix to transpose + */ +static void +transpose(GLfloat *m) +{ + GLfloat t[16] = { + m[0], m[4], m[8], m[12], + m[1], m[5], m[9], m[13], + m[2], m[6], m[10], m[14], + m[3], m[7], m[11], m[15]}; + + memcpy(m, t, sizeof(t)); +} + +/** + * Inverts a 4x4 matrix. + * + * This function can currently handle only pure translation-rotation matrices. + * Read http://www.gamedev.net/community/forums/topic.asp?topic_id=425118 + * for an explanation. + */ +static void +invert(GLfloat *m) +{ + GLfloat t[16]; + identity(t); + + // Extract and invert the translation part 't'. The inverse of a + // translation matrix can be calculated by negating the translation + // coordinates. + t[12] = -m[12]; t[13] = -m[13]; t[14] = -m[14]; + + // Invert the rotation part 'r'. The inverse of a rotation matrix is + // equal to its transpose. + m[12] = m[13] = m[14] = 0; + transpose(m); + + // inv(m) = inv(r) * inv(t) + multiply(m, t); +} + +/** + * Calculate a perspective projection transformation. + * + * @param m the matrix to save the transformation in + * @param fovy the field of view in the y direction + * @param aspect the view aspect ratio + * @param zNear the near clipping plane + * @param zFar the far clipping plane + */ +void perspective(GLfloat *m, GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) +{ + GLfloat tmp[16]; + identity(tmp); + + double sine, cosine, cotangent, deltaZ; + GLfloat radians = fovy / 2 * M_PI / 180; + + deltaZ = zFar - zNear; + sincos(radians, &sine, &cosine); + + if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) + return; + + cotangent = cosine / sine; + + tmp[0] = cotangent / aspect; + tmp[5] = cotangent; + tmp[10] = -(zFar + zNear) / deltaZ; + tmp[11] = -1; + tmp[14] = -2 * zNear * zFar / deltaZ; + tmp[15] = 0; + + memcpy(m, tmp, sizeof(tmp)); +} + +/** + * Draws a gear. + * + * @param gear the gear to draw + * @param transform the current transformation matrix + * @param x the x position to draw the gear at + * @param y the y position to draw the gear at + * @param angle the rotation angle of the gear + * @param color the color of the gear + */ +static void +draw_gear(struct gear *gear, GLfloat *transform, + GLfloat x, GLfloat y, GLfloat angle, const GLfloat color[4]) +{ + GLfloat model_view[16]; + GLfloat normal_matrix[16]; + GLfloat model_view_projection[16]; + + /* Translate and rotate the gear */ + memcpy(model_view, transform, sizeof (model_view)); + translate(model_view, x, y, 0); + rotate(model_view, 2 * M_PI * angle / 360.0, 0, 0, 1); + + /* Create and set the ModelViewProjectionMatrix */ + memcpy(model_view_projection, ProjectionMatrix, sizeof(model_view_projection)); + multiply(model_view_projection, model_view); + + glUniformMatrix4fv(ModelViewProjectionMatrix_location, 1, GL_FALSE, + model_view_projection); + + /* + * Create and set the NormalMatrix. It's the inverse transpose of the + * ModelView matrix. + */ + memcpy(normal_matrix, model_view, sizeof (normal_matrix)); + invert(normal_matrix); + transpose(normal_matrix); + glUniformMatrix4fv(NormalMatrix_location, 1, GL_FALSE, normal_matrix); + + /* Set the gear color */ + glUniform4fv(MaterialColor_location, 1, color); + + /* Set the vertex buffer object to use */ + glBindBuffer(GL_ARRAY_BUFFER, gear->vbo); + + /* Set up the position of the attributes in the vertex buffer object */ + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, + 6 * sizeof(GLfloat), NULL); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, + 6 * sizeof(GLfloat), (GLfloat *) 0 + 3); + + /* Enable the attributes */ + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + + /* Draw the triangle strips that comprise the gear */ + int n; + for (n = 0; n < gear->nstrips; n++) + glDrawArrays(GL_TRIANGLE_STRIP, gear->strips[n].first, gear->strips[n].count); + + /* Disable the attributes */ + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(0); +} + +/** + * Draws the gears. + */ +static void +gears_draw(void) +{ + const static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 }; + const static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 }; + const static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 }; + GLfloat transform[16]; + identity(transform); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* Translate and rotate the view */ + translate(transform, 0, 0, -20); + rotate(transform, 2 * M_PI * view_rot[0] / 360.0, 1, 0, 0); + rotate(transform, 2 * M_PI * view_rot[1] / 360.0, 0, 1, 0); + rotate(transform, 2 * M_PI * view_rot[2] / 360.0, 0, 0, 1); + + /* Draw the gears */ + draw_gear(gear1, transform, -3.0, -2.0, angle, red); + draw_gear(gear2, transform, 3.1, -2.0, -2 * angle - 9.0, green); + draw_gear(gear3, transform, -3.1, 4.2, -2 * angle - 25.0, blue); + + glutSwapBuffers(); +} + +/** + * Handles a new window size or exposure. + * + * @param width the window width + * @param height the window height + */ +static void +gears_reshape(int width, int height) +{ + /* Update the projection matrix */ + perspective(ProjectionMatrix, 60.0, width / (float)height, 1.0, 1024.0); + + /* Set the viewport */ + glViewport(0, 0, (GLint) width, (GLint) height); +} + +/** + * Handles special glut events. + * + * @param special the event to handle. + */ +static void +gears_special(int special, int crap, int morecrap) +{ + switch (special) { + case GLUT_KEY_LEFT: + view_rot[1] += 5.0; + break; + case GLUT_KEY_RIGHT: + view_rot[1] -= 5.0; + break; + case GLUT_KEY_UP: + view_rot[0] += 5.0; + break; + case GLUT_KEY_DOWN: + view_rot[0] -= 5.0; + break; + } +} + +static void +gears_idle(void) +{ + static int frames = 0; + static double tRot0 = -1.0, tRate0 = -1.0; + double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; + + if (tRot0 < 0.0) + tRot0 = t; + dt = t - tRot0; + tRot0 = t; + + /* advance rotation for next frame */ + angle += 70.0 * dt; /* 70 degrees per second */ + if (angle > 3600.0) + angle -= 3600.0; + + glutPostRedisplay(); + frames++; + + if (tRate0 < 0.0) + tRate0 = t; + if (t - tRate0 >= 5.0) { + GLfloat seconds = t - tRate0; + GLfloat fps = frames / seconds; + printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds, + fps); + tRate0 = t; + frames = 0; + } +} + +static const char vertex_shader[] = +"attribute vec3 position;\n" +"attribute vec3 normal;\n" +"\n" +"uniform mat4 ModelViewProjectionMatrix;\n" +"uniform mat4 NormalMatrix;\n" +"uniform vec4 LightSourcePosition;\n" +"uniform vec4 MaterialColor;\n" +"\n" +"varying vec4 Color;\n" +"\n" +"void main(void)\n" +"{\n" +" // Transform the normal to eye coordinates\n" +" vec3 N = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));\n" +"\n" +" // The LightSourcePosition is actually its direction for directional light\n" +" vec3 L = normalize(LightSourcePosition.xyz);\n" +"\n" +" // Multiply the diffuse value by the vertex color (which is fixed in this case)\n" +" // to get the actual color that we will use to draw this vertex with\n" +" float diffuse = max(dot(N, L), 0.0);\n" +" Color = diffuse * MaterialColor;\n" +"\n" +" // Transform the position to clip coordinates\n" +" gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);\n" +"}"; + +static const char fragment_shader[] = +"#ifdef GL_ES\n" +"precision mediump float;\n" +"#endif\n" +"varying vec4 Color;\n" +"\n" +"void main(void)\n" +"{\n" +" gl_FragColor = Color;\n" +"}"; + +static void +gears_init(void) +{ + GLuint v, f, program; + const char *p; + char msg[512]; + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + /* Compile the vertex shader */ + p = vertex_shader; + v = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(v, 1, &p, NULL); + glCompileShader(v); + glGetShaderInfoLog(v, sizeof msg, NULL, msg); + printf("vertex shader info: %s\n", msg); + + /* Compile the fragment shader */ + p = fragment_shader; + f = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(f, 1, &p, NULL); + glCompileShader(f); + glGetShaderInfoLog(f, sizeof msg, NULL, msg); + printf("fragment shader info: %s\n", msg); + + /* Create and link the shader program */ + program = glCreateProgram(); + glAttachShader(program, v); + glAttachShader(program, f); + glBindAttribLocation(program, 0, "position"); + glBindAttribLocation(program, 1, "normal"); + + glLinkProgram(program); + glGetProgramInfoLog(program, sizeof msg, NULL, msg); + printf("info: %s\n", msg); + + /* Enable the shaders */ + glUseProgram(program); + + /* Get the locations of the uniforms so we can access them */ + ModelViewProjectionMatrix_location = glGetUniformLocation(program, "ModelViewProjectionMatrix"); + NormalMatrix_location = glGetUniformLocation(program, "NormalMatrix"); + LightSourcePosition_location = glGetUniformLocation(program, "LightSourcePosition"); + MaterialColor_location = glGetUniformLocation(program, "MaterialColor"); + + /* Set the LightSourcePosition uniform which is constant throught the program */ + glUniform4fv(LightSourcePosition_location, 1, LightSourcePosition); + + /* make the gears */ + gear1 = create_gear(1.0, 4.0, 1.0, 20, 0.7); + gear2 = create_gear(0.5, 2.0, 2.0, 10, 0.7); + gear3 = create_gear(1.3, 2.0, 0.5, 10, 0.7); +} + +int +main(int argc, char *argv[]) +{ + /* Initialize the window */ + glutInit(&argc, argv); + glutInitWindowSize(300, 300); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + + glutCreateWindow("es2gears"); + + /* Set up glut callback functions */ + gears_idle(); + glutReshapeFunc(gears_reshape); + glutDisplayFunc(gears_draw); + glutSpecialFunc(gears_special); + + /* Initialize the gears */ + gears_init(); + + glutMainLoop(); + + return 0; +} diff --git a/tests/hello_world_gles_shell.html b/tests/hello_world_gles_shell.html new file mode 100644 index 00000000..ad2c5a87 --- /dev/null +++ b/tests/hello_world_gles_shell.html @@ -0,0 +1,55 @@ +<html> + <head> + <title>Emscripten-Generated Code</title> + <body> + <center> + <canvas id='canvas' width='256' height='256'></canvas> + </center> + <hr> + <div id='output'></div> + <hr> + <script type='text/javascript'> + /** + * TODO: Encapsulate this part in a reusable token such as + * EMSCRIPTEN_ENVIRONMENT so that we can share code + * between the default shell and custom ones. + */ + // connect to canvas + var Module = { + print: (function() { + var element = document.getElementById('output'); + return function(text) { + element.innerHTML += text.replace('\n', '<br>', 'g') + '<br>'; + }; + })(), + canvas: document.getElementById('canvas') + }; + + // The compiled code + {{{ SCRIPT_CODE }}} + + // Test code + function simulateKeyEvent(keyCode) { + var event = document.createEvent("KeyboardEvent"); + event.initKeyEvent("keydown", true, true, window, + 0, 0, 0, 0, keyCode, 0); + document.body.dispatchEvent(event); + } + function reportResult(result) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'http://localhost:8888/report_gl_result?' + result, true); + xhr.send(); + } + function doTest() { + var firstImage = Module.canvas.toDataURL(); + simulateKeyEvent(0x25 /* DOM_VK_LEFT */); + setTimeout(function() { + var secondImage = Module.canvas.toDataURL(); + reportResult(firstImage != secondImage); + }, 0); + } + addEventListener("load", doTest, false); + </script> + </body> +</html> + diff --git a/tests/runner.py b/tests/runner.py index 4cdd14f8..cbff37eb 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -14,7 +14,7 @@ will use 4 processes. To install nose do something like ''' from subprocess import Popen, PIPE, STDOUT -import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, tempfile, re, difflib, webbrowser +import os, unittest, tempfile, shutil, time, inspect, sys, math, glob, tempfile, re, difflib, webbrowser, hashlib, BaseHTTPServer, threading # Setup @@ -195,9 +195,6 @@ process(sys.argv[1]) assert 'strict warning:' not in ret, 'We should pass all strict mode checks: ' + ret return ret - def run_llvm_interpreter(self, args): - return Popen([EXEC_LLVM] + args, stdout=PIPE, stderr=self.stderr_redirect).communicate()[0] - def build_native(self, filename): Popen([CLANG, '-O2', filename, '-o', filename+'.native'], stdout=PIPE).communicate()[0] @@ -266,7 +263,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv): class T(RunnerCore): # Short name, to make it more fun to use manually on the commandline ## Does a complete test - builds, runs, checks output, etc. - def do_run(self, src, expected_output=None, args=[], output_nicerizer=None, output_processor=None, no_build=False, main_file=None, additional_files=[], js_engines=None, post_build=None, basename='src.cpp', libraries=[], includes=[], force_c=False, build_ll_hook=None, extra_emscripten_args=[]): + def do_run(self, src, expected_output, args=[], output_nicerizer=None, output_processor=None, no_build=False, main_file=None, additional_files=[], js_engines=None, post_build=None, basename='src.cpp', libraries=[], includes=[], force_c=False, build_ll_hook=None, extra_emscripten_args=[]): if force_c or (main_file is not None and main_file[-2:]) == '.c': basename = 'src.c' Building.COMPILER = to_cc(Building.COMPILER) @@ -277,11 +274,6 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv): self.build(src, dirname, filename, main_file=main_file, additional_files=additional_files, libraries=libraries, includes=includes, build_ll_hook=build_ll_hook, extra_emscripten_args=extra_emscripten_args, post_build=post_build) - # If not provided with expected output, then generate it right now, using lli - if expected_output is None: - expected_output = self.run_llvm_interpreter([filename + '.o']) - print '[autogenerated expected output: %20s]' % (expected_output[0:30].replace('\n', '|')+'...') - # Run in both JavaScript engines, if optimizing - significant differences there (typed arrays) if js_engines is None: js_engines = JS_ENGINES @@ -691,7 +683,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv): return 0; } ''' - self.do_run(src)#, '*4294967295,0,4294967219*\n*-1,1,-1,1*\n*-2,1,-2,1*\n*246,296*\n*1,0*') + self.do_run(src, '*4294967295,0,4294967219*\n*-1,1,-1,1*\n*-2,1,-2,1*\n*246,296*\n*1,0*') # Now let's see some code that should just work in USE_TYPED_ARRAYS == 2, but requires # corrections otherwise @@ -800,6 +792,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv): def test_math(self): src = ''' #include <stdio.h> + #include <stdlib.h> #include <cmath> int main() { @@ -812,11 +805,22 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv): printf(",%d", isinf(INFINITY) != 0); printf(",%d", isinf(-INFINITY) != 0); printf(",%d", isinf(12.3) != 0); + div_t div_result = div(23, 10); + printf(",%d", div_result.quot); + printf(",%d", div_result.rem); + double sine = -1.0, cosine = -1.0; + sincos(0.0, &sine, &cosine); + printf(",%1.1lf", sine); + printf(",%1.1lf", cosine); + float fsine = -1.0f, fcosine = -1.0f; + sincosf(0.0, &fsine, &fcosine); + printf(",%1.1f", fsine); + printf(",%1.1f", fcosine); printf("*\\n"); return 0; } ''' - self.do_run(src, '*3.14,-3.14,1,0,0,0,1,0,1,1,0*') + self.do_run(src, '*3.14,-3.14,1,0,0,0,1,0,1,1,0,2,3,0.0,1.0,0.0,1.0*') def test_math_hyperbolic(self): src = open(path_from_root('tests', 'hyperbolic', 'src.c'), 'r').read() @@ -893,7 +897,7 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv): } ''' - self.do_run(src) + self.do_run(src, '*1800*') generated = open('src.cpp.o.js', 'r').read() assert '__label__ ==' not in generated, 'We should hoist into the loop' @@ -2387,7 +2391,10 @@ def process(filename): return 0; } ''' - self.do_run(src) + def check(result): + return hashlib.sha1(result).hexdigest() + self.do_run(src, '6c9cdfe937383b79e52ca7a2cce83a21d9f5422c', + output_nicerizer = check) def test_memmove(self): src = ''' @@ -2400,7 +2407,7 @@ def process(filename): return 0; } ''' - self.do_run(src) + self.do_run(src, 'memmove can be very very useful') def test_bsearch(self): if Settings.QUANTUM_SIZE == 1: return self.skip('Test cannot work with q1') @@ -3176,21 +3183,21 @@ at function.:blag #include <stdlib.h> int main () { - printf("%d\n", atoi("")); - printf("%d\n", atoi("a")); - printf("%d\n", atoi(" b")); - printf("%d\n", atoi(" c ")); - printf("%d\n", atoi("6")); - printf("%d\n", atoi(" 5")); - printf("%d\n", atoi("4 ")); - printf("%d\n", atoi("3 6")); - printf("%d\n", atoi(" 3 7")); - printf("%d\n", atoi("9 d")); + printf("%d*", atoi("")); + printf("%d*", atoi("a")); + printf("%d*", atoi(" b")); + printf("%d*", atoi(" c ")); + printf("%d*", atoi("6")); + printf("%d*", atoi(" 5")); + printf("%d*", atoi("4 ")); + printf("%d*", atoi("3 6")); + printf("%d*", atoi(" 3 7")); + printf("%d*", atoi("9 d")); printf("%d\n", atoi(" 8 e")); return 0; } ''' - self.do_run(src) + self.do_run(src, '0*0*0*0*6*5*4*3*3*9*8') def test_sscanf(self): src = r''' @@ -3216,7 +3223,8 @@ at function.:blag return 0; } ''' - self.do_run(src) + self.do_run(src, 'en-us : 2*en-r : 99*en : 3*1.234567, 0.000000', + output_nicerizer = lambda x: x.replace('\n', '*')) # Part 2: doubles (issue 148) if Settings.USE_TYPED_ARRAYS == 2: @@ -3267,7 +3275,11 @@ Pass: 123456.789063 123456.789063 Pass: 0.000012 0.000012 Pass: 0.000012 0.000012''') else: - self.do_run(src) + self.do_run(src, '''Pass: 1.234568 1.234568 +Pass: 123456.789000 123456.789000 +Pass: 123456.789000 123456.789000 +Pass: 0.000012 0.000012 +Pass: 0.000012 0.000012''') def test_langinfo(self): src = open(path_from_root('tests', 'langinfo', 'test.c'), 'r').read() @@ -3872,6 +3884,18 @@ def process(filename): ''' self.do_run(src, re.sub('(^|\n)\s+', '\\1', expected)) + def test_inet(self): + src = r''' + #include <stdio.h> + #include <arpa/inet.h> + + int main() { + printf("*%x,%x,%x,%x*\n", htonl(0x12345678), htons(0xabcd), ntohl(0x43211234), ntohs(0xbeaf)); + return 0; + } + ''' + self.do_run(src, '*78563412,cdab,34122143,afbe*') + def test_ctype(self): # The bit fiddling done by the macros using __ctype_b_loc requires this. Settings.CORRECT_SIGNS = 1 @@ -4483,7 +4507,7 @@ def process(filename): self.do_autodebug(filename) # Compare to each other, and to expected output - self.do_ll_run(path_from_root('tests', filename+'.o.ll.ll')) + self.do_ll_run(path_from_root('tests', filename+'.o.ll.ll'), '''AD:-1,1''') assert open('stdout').read().startswith('AD:-1'), 'We must note when we enter functions' # Test using build_ll_hook @@ -4502,8 +4526,7 @@ def process(filename): return 0; } ''' - self.do_run(src, build_ll_hook=self.do_autodebug) - self.do_run(src, 'AD:', build_ll_hook=self.do_autodebug) + self.do_run(src, '''AD:-1,1''', build_ll_hook=self.do_autodebug) def test_profiling(self): src = ''' @@ -5351,10 +5374,16 @@ Options that are modified or new in %s include: for args in [['-c'], ['-o', 'src.o'], ['-o', 'src.bc'], ['-o', 'js']]: target = args[1] if len(args) == 2 else 'hello_world.o' clear() - output = Popen([compiler, path_from_root('tests', 'hello_world' + suffix)] + args, stdout=PIPE, stderr=PIPE).communicate() + Popen([compiler, path_from_root('tests', 'hello_world' + suffix)] + args, stdout=PIPE, stderr=PIPE).communicate() + syms = Building.llvm_nm(target) + assert len(syms.defs) == 1 and 'main' in syms.defs, 'Failed to generate valid bitcode' + if target == 'js': # make sure emcc can recognize the target as a bitcode file + shutil.move(target, target + '.bc') + target += '.bc' + output = Popen([compiler, target, '-o', target + '.js'], stdout = PIPE, stderr = PIPE).communicate() assert len(output[0]) == 0, output[0] - assert os.path.exists(target), 'Expected %s to exist since args are %s : %s' % (target, str(args), '\n'.join(output)) - self.assertContained('hello, world!', self.run_llvm_interpreter([target])) + assert os.path.exists(target + '.js'), 'Expected %s to exist since args are %s : %s' % (target + '.js', str(args), '\n'.join(output)) + self.assertContained('hello, world!', run_js(target + '.js')) # emcc src.ll ==> generates .js clear() @@ -5499,8 +5528,12 @@ Options that are modified or new in %s include: try_delete(target) assert not os.path.exists(target) output = Popen([compiler, 'twopart_main.o', 'twopart_side.o', '-o', 'combined.bc'] + args, stdout=PIPE, stderr=PIPE).communicate() - assert os.path.exists('combined.bc'), '\n'.join(output) - self.assertContained('side got: hello from main, over', self.run_llvm_interpreter(['combined.bc'])) + syms = Building.llvm_nm('combined.bc') + assert len(syms.defs) == 2 and 'main' in syms.defs, 'Failed to generate valid bitcode' + output = Popen([compiler, 'combined.bc', '-o', 'combined.bc.js'], stdout = PIPE, stderr = PIPE).communicate() + assert len(output[0]) == 0, output[0] + assert os.path.exists('combined.bc.js'), 'Expected %s to exist' % ('combined.bc.js') + self.assertContained('side got: hello from main, over', run_js('combined.bc.js')) # --js-transform <transform> clear() @@ -5520,13 +5553,32 @@ f.close() # TODO: test normal project linking, static and dynamic: get_library should not need to be told what to link! # TODO: deprecate llvm optimizations, dlmalloc, etc. in emscripten.py. + # For browser tests which report their success + def run_test_server(expectedResult): + class TestServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): + def do_GET(s): + assert s.path == expectedResult, 'Expected %s, got %s' % (expectedResult, s.path) + httpd.shutdown() + def handle_timeout(): + assert False, 'Timed out while waiting for the browser test to finish' + httpd.shutdown() + httpd = BaseHTTPServer.HTTPServer(('localhost', 8888), TestServerHandler) + httpd.timeout = 5; + server_thread = threading.Thread(target=httpd.serve_forever) + server_thread.daemon = True + server_thread.start() + server_thread.join(5.5) + # Finally, do some web browser tests - def run_browser(html_file, message): - webbrowser.open_new(html_file) + def run_browser(html_file, message, expectedResult = None): + webbrowser.open_new(os.path.abspath(html_file)) print 'A web browser window should have opened a page containing the results of a part of this test.' print 'You need to manually look at the page to see that it works ok: ' + message print '(sleeping for a bit to keep the directory alive for the web browser..)' - time.sleep(5) + if expectedResult is not None: + run_test_server(expectedResult) + else: + time.sleep(5) print '(moving on..)' # test HTML generation. @@ -5558,6 +5610,16 @@ f.close() html_file.close() run_browser('main.html', 'You should see that the worker was called, and said "hello from worker!"') + # test the OpenGL ES implementation + clear() + output = Popen([EMCC, path_from_root('tests', 'hello_world_gles.c'), '-o', 'something.html', + '-DHAVE_BUILTIN_SINCOS', + '--shell-file', path_from_root('tests', 'hello_world_gles_shell.html')], + stdout=PIPE, stderr=PIPE).communicate() + assert len(output[0]) == 0, output[0] + assert os.path.exists('something.html'), output + run_browser('something.html', 'You should see animating gears.', '/report_gl_result?true') + def test_eliminator(self): input = open(path_from_root('tools', 'eliminator', 'eliminator-test.js')).read() expected = open(path_from_root('tools', 'eliminator', 'eliminator-test-output.js')).read() |