summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--src/jsifier.js1
-rw-r--r--src/library.js1
-rw-r--r--src/library_gl.js1492
-rw-r--r--src/library_sdl.js5
-rw-r--r--src/parseTools.js10
-rw-r--r--src/relooper/Relooper.cpp127
-rw-r--r--src/relooper/Relooper.h7
-rw-r--r--src/relooper/fuzzer.py4
-rw-r--r--src/relooper/test.cpp41
-rw-r--r--src/relooper/test.txt27
-rw-r--r--src/relooper/test4.txt1
-rw-r--r--src/relooper/test_debug.txt76
-rw-r--r--src/relooper/test_fuzz1.txt11
-rw-r--r--src/relooper/test_fuzz5.txt24
-rw-r--r--src/relooper/test_fuzz6.txt1
-rwxr-xr-xsrc/relooper/testit.sh2
-rwxr-xr-xsrc/relooper/updateit.sh2
-rw-r--r--system/include/libcxx/exception4
-rw-r--r--tests/aniso.c16
-rw-r--r--tests/cases/fp80_ta2.ll (renamed from tests/cases/fp80.ll)0
-rw-r--r--tests/cases/muli33_ta2.ll114
-rw-r--r--tests/cases/muli33_ta2.txt1
-rw-r--r--tests/cases/philoop_ta2.ll (renamed from tests/cases/philoop.ll)0
-rw-r--r--tests/cases/philoop_ta2.txt (renamed from tests/cases/philoop.txt)0
-rw-r--r--tests/files.cpp3
-rw-r--r--tests/full_es2_sdlproc.c727
-rw-r--r--tests/gl_ps.c40
-rw-r--r--tests/gl_ps_workaround.c230
-rw-r--r--tests/gl_ps_workaround2.c230
-rw-r--r--tests/glbegin_points.c44
-rwxr-xr-xtests/runner.py139
-rw-r--r--tests/s3tc.c16
-rw-r--r--tests/s3tc_crunch.c16
-rw-r--r--tests/sdl_fog_density.c48
-rw-r--r--tests/sdl_fog_exp2.c48
-rw-r--r--tests/sdl_fog_linear.c48
-rw-r--r--tests/sdl_fog_negative.c48
-rw-r--r--tests/sdl_fog_simple.c51
-rw-r--r--tests/sdl_ogl.c48
-rw-r--r--tests/sdl_ogl_defaultMatrixMode.c46
-rw-r--r--tests/sdl_ogl_p.c44
-rw-r--r--third_party/lzma.js/lzip/Makefile18
-rw-r--r--tools/shared.py2
44 files changed, 2709 insertions, 1105 deletions
diff --git a/AUTHORS b/AUTHORS
index 368387a7..0d139781 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -77,4 +77,5 @@ a license to everyone to use it as detailed in LICENSE.)
* Martin Gerhardy <martin.gerhardy@gmail.com>
* James Gregory <jgregory@zynga.com> (copyright owned by Zynga, Inc)
* Dan Gohman <sunfish@google.com> (copyright owned by Google, Inc.)
+* Jeff Gilbert <jgilbert@mozilla.com> (copyright owned by Mozilla Foundation)
diff --git a/src/jsifier.js b/src/jsifier.js
index 77aff895..156fd65d 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -460,6 +460,7 @@ function JSify(data, functionsOnly, givenFunctions) {
} else {
ident = '_' + ident;
}
+ if (VERBOSE) printErr('adding ' + ident + ' and deps ' + deps);
var depsText = (deps ? '\n' + deps.map(addFromLibrary).filter(function(x) { return x != '' }).join('\n') : '');
var contentText = isFunction ? snippet : ('var ' + ident + '=' + snippet + ';');
if (ASM_JS) {
diff --git a/src/library.js b/src/library.js
index e65754ba..51c4c5cb 100644
--- a/src/library.js
+++ b/src/library.js
@@ -560,6 +560,7 @@ LibraryManager.library = {
var stdout = FS.createDevice(devFolder, 'stdout', null, output);
var stderr = FS.createDevice(devFolder, 'stderr', null, error);
FS.createDevice(devFolder, 'tty', input, output);
+ FS.createDevice(devFolder, 'null', function(){}, function(){});
// Create default streams.
FS.streams[1] = {
diff --git a/src/library_gl.js b/src/library_gl.js
index ba99eaa8..1fa0cc9c 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -373,7 +373,7 @@ var LibraryGL = {
glGetIntegerv__sig: 'vii',
glGetIntegerv: function(name_, p) {
- switch(name_) { // Handle a few trivial GLES values
+ switch(name_) { // Handle a few trivial GLES values
case 0x8DFA: // GL_SHADER_COMPILER
{{{ makeSetValue('p', '0', '1', 'i32') }}};
return;
@@ -507,7 +507,7 @@ var LibraryGL = {
glGenTextures__sig: 'vii',
glGenTextures: function(n, textures) {
for (var i = 0; i < n; i++) {
- var id = GL.getNewId(GL.textures);
+ var id = GL.getNewId(GL.textures);
GL.textures[id] = Module.ctx.createTexture();
{{{ makeSetValue('textures', 'i*4', 'id', 'i32') }}};
}
@@ -726,7 +726,7 @@ var LibraryGL = {
var ptable = GL.uniformTable[program];
if (!ptable) ptable = GL.uniformTable[program] = {};
var id = ptable[name];
- if (id) return id;
+ if (id) return id;
var loc = Module.ctx.getUniformLocation(GL.programs[program], name);
if (!loc) return -1;
id = GL.getNewId(GL.uniforms);
@@ -989,13 +989,15 @@ var LibraryGL = {
glBindBuffer__sig: 'vii',
glBindBuffer: function(target, buffer) {
+ var bufferObj = buffer ? GL.buffers[buffer] : null;
+
if (target == Module.ctx.ARRAY_BUFFER) {
GL.currArrayBuffer = buffer;
} else if (target == Module.ctx.ELEMENT_ARRAY_BUFFER) {
GL.currElementArrayBuffer = buffer;
}
- Module.ctx.bindBuffer(target, buffer ? GL.buffers[buffer] : null);
+ Module.ctx.bindBuffer(target, bufferObj);
},
glVertexAttrib1fv__sig: 'vii',
@@ -1275,7 +1277,22 @@ var LibraryGL = {
currentVao: null,
enabledVertexAttribArrays: {}, // helps with vao cleanups
+ hasRunInit: false,
+
init: function() {
+ // Do not activate immediate/emulation code (e.g. replace glDrawElements) when in FULL_ES2 mode.
+ // We do not need full emulation, we instead emulate client-side arrays etc. in FULL_ES2 code in
+ // a straightforward manner, and avoid not having a bound buffer be ambiguous between es2 emulation
+ // code and legacy gl emulation code.
+#if FULL_ES2
+ return;
+#endif
+
+ if (GLEmulation.hasRunInit) {
+ return;
+ }
+ GLEmulation.hasRunInit = true;
+
GLEmulation.fogColor = new Float32Array(4);
// Add some emulation workarounds
@@ -1297,6 +1314,7 @@ var LibraryGL = {
0x80A0: 1 // GL_SAMPLE_COVERAGE
};
+ var glEnable = _glEnable;
_glEnable = function(cap) {
// Clean up the renderer on any change to the rendering state. The optimization of
// skipping renderer setup is aimed at the case of multiple glDraw* right after each other
@@ -1307,13 +1325,18 @@ var LibraryGL = {
} else if (cap == 0x0de1 /* GL_TEXTURE_2D */) {
// XXX not according to spec, and not in desktop GL, but works in some GLES1.x apparently, so support
// it by forwarding to glEnableClientState
+ /* Actually, let's not, for now. (This sounds exceedingly broken)
+ * This is in gl_ps_workaround2.c.
_glEnableClientState(cap);
+ */
return;
} else if (!(cap in validCapabilities)) {
return;
}
- Module.ctx.enable(cap);
+ glEnable(cap);
};
+
+ var glDisable = _glDisable;
_glDisable = function(cap) {
if (GL.immediate.lastRenderer) GL.immediate.lastRenderer.cleanup();
if (cap == 0x0B60 /* GL_FOG */) {
@@ -1322,12 +1345,15 @@ var LibraryGL = {
} else if (cap == 0x0de1 /* GL_TEXTURE_2D */) {
// XXX not according to spec, and not in desktop GL, but works in some GLES1.x apparently, so support
// it by forwarding to glDisableClientState
+ /* Actually, let's not, for now. (This sounds exceedingly broken)
+ * This is in gl_ps_workaround2.c.
_glDisableClientState(cap);
+ */
return;
} else if (!(cap in validCapabilities)) {
return;
}
- Module.ctx.disable(cap);
+ glDisable(cap);
};
_glIsEnabled = function(cap) {
if (cap == 0x0B60 /* GL_FOG */) {
@@ -1453,6 +1479,7 @@ var LibraryGL = {
_glShaderSource = function(shader, count, string, length) {
var source = GL.getSource(shader, count, string, length);
#if GL_DEBUG
+ console.log("glShaderSource: Input: \n" + source);
GL.shaderOriginalSources[shader] = source;
#endif
// XXX We add attributes and uniforms to shaders. The program can ask for the # of them, and see the
@@ -1510,9 +1537,7 @@ var LibraryGL = {
}
if (source.indexOf('gl_Color') >= 0) {
source = 'attribute vec4 a_color; \n' +
- 'uniform vec4 u_color; \n' +
- 'uniform int u_hasColorAttrib; \n' +
- source.replace(/gl_Color/g, '(u_hasColorAttrib > 0 ? a_color : u_color)');
+ source.replace(/gl_Color/g, 'a_color');
}
if (source.indexOf('gl_Normal') >= 0) {
source = 'attribute vec3 a_normal; \n' +
@@ -1558,6 +1583,7 @@ var LibraryGL = {
}
#if GL_DEBUG
GL.shaderSources[shader] = source;
+ console.log("glShaderSource: Output: \n" + source);
#endif
Module.ctx.shaderSource(GL.shaders[shader], source);
};
@@ -1706,8 +1732,12 @@ var LibraryGL = {
getAttributeFromCapability: function(cap) {
var attrib = null;
switch (cap) {
- case 0x8078: // GL_TEXTURE_COORD_ARRAY
case 0x0de1: // GL_TEXTURE_2D - XXX not according to spec, and not in desktop GL, but works in some GLES1.x apparently, so support it
+#if ASSERTIONS
+ abort("GL_TEXTURE_2D is not a spec-defined capability for gl{Enable,Disable}ClientState.");
+#endif
+ // Fall through:
+ case 0x8078: // GL_TEXTURE_COORD_ARRAY
attrib = GL.immediate.TEXTURE0 + GL.immediate.clientActiveTexture; break;
case 0x8074: // GL_VERTEX_ARRAY
attrib = GL.immediate.VERTEX; break;
@@ -1767,19 +1797,19 @@ var LibraryGL = {
case 'glEnableVertexAttribArray': ret = {{{ Functions.getIndex('_glEnableVertexAttribArray', true) }}}; break;
case 'glDisableVertexAttribArray': ret = {{{ Functions.getIndex('_glDisableVertexAttribArray', true) }}}; break;
case 'glVertexAttribPointer': ret = {{{ Functions.getIndex('_glVertexAttribPointer', true) }}}; break;
- case 'glVertexAttrib1f': ret = {{{ Functions.getIndex('_glVertexAttrib1f', true) }}}; break;
- case 'glVertexAttrib2f': ret = {{{ Functions.getIndex('_glVertexAttrib2f', true) }}}; break;
- case 'glVertexAttrib3f': ret = {{{ Functions.getIndex('_glVertexAttrib3f', true) }}}; break;
- case 'glVertexAttrib4f': ret = {{{ Functions.getIndex('_glVertexAttrib4f', true) }}}; break;
- case 'glVertexAttrib1fv': ret = {{{ Functions.getIndex('_glVertexAttrib1fv', true) }}}; break;
- case 'glVertexAttrib2fv': ret = {{{ Functions.getIndex('_glVertexAttrib2fv', true) }}}; break;
- case 'glVertexAttrib3fv': ret = {{{ Functions.getIndex('_glVertexAttrib3fv', true) }}}; break;
- case 'glVertexAttrib4fv': ret = {{{ Functions.getIndex('_glVertexAttrib4fv', true) }}}; break;
- case 'glGetVertexAttribfv': ret = {{{ Functions.getIndex('_glGetVertexAttribfv', true) }}}; break;
- case 'glGetVertexAttribiv': ret = {{{ Functions.getIndex('_glGetVertexAttribiv', true) }}}; break;
- case 'glGetVertexAttribPointerv': ret = {{{ Functions.getIndex('_glGetVertexAttribPointerv', true) }}}; break;
- case 'glGetAttribLocation': ret = {{{ Functions.getIndex('_glGetAttribLocation', true) }}}; break;
- case 'glGetActiveAttrib': ret = {{{ Functions.getIndex('_glGetActiveAttrib', true) }}}; break;
+ case 'glVertexAttrib1f': ret = {{{ Functions.getIndex('_glVertexAttrib1f', true) }}}; break;
+ case 'glVertexAttrib2f': ret = {{{ Functions.getIndex('_glVertexAttrib2f', true) }}}; break;
+ case 'glVertexAttrib3f': ret = {{{ Functions.getIndex('_glVertexAttrib3f', true) }}}; break;
+ case 'glVertexAttrib4f': ret = {{{ Functions.getIndex('_glVertexAttrib4f', true) }}}; break;
+ case 'glVertexAttrib1fv': ret = {{{ Functions.getIndex('_glVertexAttrib1fv', true) }}}; break;
+ case 'glVertexAttrib2fv': ret = {{{ Functions.getIndex('_glVertexAttrib2fv', true) }}}; break;
+ case 'glVertexAttrib3fv': ret = {{{ Functions.getIndex('_glVertexAttrib3fv', true) }}}; break;
+ case 'glVertexAttrib4fv': ret = {{{ Functions.getIndex('_glVertexAttrib4fv', true) }}}; break;
+ case 'glGetVertexAttribfv': ret = {{{ Functions.getIndex('_glGetVertexAttribfv', true) }}}; break;
+ case 'glGetVertexAttribiv': ret = {{{ Functions.getIndex('_glGetVertexAttribiv', true) }}}; break;
+ case 'glGetVertexAttribPointerv': ret = {{{ Functions.getIndex('_glGetVertexAttribPointerv', true) }}}; break;
+ case 'glGetAttribLocation': ret = {{{ Functions.getIndex('_glGetAttribLocation', true) }}}; break;
+ case 'glGetActiveAttrib': ret = {{{ Functions.getIndex('_glGetActiveAttrib', true) }}}; break;
case 'glBindRenderbuffer': ret = {{{ Functions.getIndex('_glBindRenderbuffer', true) }}}; break;
case 'glDeleteRenderbuffers': ret = {{{ Functions.getIndex('_glDeleteRenderbuffers', true) }}}; break;
case 'glGenRenderbuffers': ret = {{{ Functions.getIndex('_glGenRenderbuffers', true) }}}; break;
@@ -1798,86 +1828,86 @@ var LibraryGL = {
case 'glDeleteVertexArrays': ret = {{{ Functions.getIndex('_glDeleteVertexArrays', true) }}}; break;
case 'glBindVertexArray': ret = {{{ Functions.getIndex('_glBindVertexArray', true) }}}; break;
case 'glGetString': ret = {{{ Functions.getIndex('_glGetString', true) }}}; break;
- case 'glBindTexture': ret = {{{ Functions.getIndex('_glBindTexture', true) }}}; break;
- case 'glGetBufferParameteriv': ret = {{{ Functions.getIndex('_glGetBufferParameteriv', true) }}}; break;
- case 'glIsBuffer': ret = {{{ Functions.getIndex('_glIsBuffer', true) }}}; break;
- case 'glDeleteShader': ret = {{{ Functions.getIndex('_glDeleteShader', true) }}}; break;
+ case 'glBindTexture': ret = {{{ Functions.getIndex('_glBindTexture', true) }}}; break;
+ case 'glGetBufferParameteriv': ret = {{{ Functions.getIndex('_glGetBufferParameteriv', true) }}}; break;
+ case 'glIsBuffer': ret = {{{ Functions.getIndex('_glIsBuffer', true) }}}; break;
+ case 'glDeleteShader': ret = {{{ Functions.getIndex('_glDeleteShader', true) }}}; break;
case 'glUniformMatrix2fv': ret = {{{ Functions.getIndex('_glUniformMatrix2fv', true) }}}; break;
case 'glUniformMatrix3fv': ret = {{{ Functions.getIndex('_glUniformMatrix3fv', true) }}}; break;
case 'glUniformMatrix4fv': ret = {{{ Functions.getIndex('_glUniformMatrix4fv', true) }}}; break;
- case 'glIsRenderbuffer': ret = {{{ Functions.getIndex('_glIsRenderbuffer', true) }}}; break;
- case 'glBlendEquation': ret = {{{ Functions.getIndex('_glBlendEquation', true) }}}; break;
- case 'glBlendFunc': ret = {{{ Functions.getIndex('_glBlendFunc', true) }}}; break;
- case 'glBlendFuncSeparate': ret = {{{ Functions.getIndex('_glBlendFuncSeparate', true) }}}; break;
- case 'glBlendEquationSeparate': ret = {{{ Functions.getIndex('_glBlendEquationSeparate', true) }}}; break;
- case 'glDepthRangef': ret = {{{ Functions.getIndex('_glDepthRangef', true) }}}; break;
- case 'glClear': ret = {{{ Functions.getIndex('_glClear', true) }}}; break;
- case 'glGenerateMipmap': ret = {{{ Functions.getIndex('_glGenerateMipmap', true) }}}; break;
- case 'glBlendColor': ret = {{{ Functions.getIndex('_glBlendColor', true) }}}; break;
- case 'glClearDepthf': ret = {{{ Functions.getIndex('_glClearDepthf', true) }}}; break;
- case 'glDeleteProgram': ret = {{{ Functions.getIndex('_glDeleteProgram', true) }}}; break;
- case 'glUniformMatrix3fv': ret = {{{ Functions.getIndex('_glUniformMatrix3fv', true) }}}; break;
- case 'glClearColor': ret = {{{ Functions.getIndex('_glClearColor', true) }}}; break;
- case 'glGetRenderbufferParameteriv': ret = {{{ Functions.getIndex('_glGetRenderbufferParameteriv', true) }}}; break;
- case 'glGetShaderInfoLog': ret = {{{ Functions.getIndex('_glGetShaderInfoLog', true) }}}; break;
- case 'glUniformMatrix4fv': ret = {{{ Functions.getIndex('_glUniformMatrix4fv', true) }}}; break;
- case 'glClearStencil': ret = {{{ Functions.getIndex('_glClearStencil', true) }}}; break;
- case 'glGetProgramInfoLog': ret = {{{ Functions.getIndex('_glGetProgramInfoLog', true) }}}; break;
- case 'glGetUniformfv': ret = {{{ Functions.getIndex('_glGetUniformfv', true) }}}; break;
- case 'glStencilFuncSeparate': ret = {{{ Functions.getIndex('_glStencilFuncSeparate', true) }}}; break;
- case 'glSampleCoverage': ret = {{{ Functions.getIndex('_glSampleCoverage', true) }}}; break;
- case 'glColorMask': ret = {{{ Functions.getIndex('_glColorMask', true) }}}; break;
- case 'glGetShaderiv': ret = {{{ Functions.getIndex('_glGetShaderiv', true) }}}; break;
- case 'glGetUniformiv': ret = {{{ Functions.getIndex('_glGetUniformiv', true) }}}; break;
- case 'glCopyTexSubImage2D': ret = {{{ Functions.getIndex('_glCopyTexSubImage2D', true) }}}; break;
- case 'glDetachShader': ret = {{{ Functions.getIndex('_glDetachShader', true) }}}; break;
- case 'glGetShaderSource': ret = {{{ Functions.getIndex('_glGetShaderSource', true) }}}; break;
- case 'glDeleteTextures': ret = {{{ Functions.getIndex('_glDeleteTextures', true) }}}; break;
- case 'glGetAttachedShaders': ret = {{{ Functions.getIndex('_glGetAttachedShaders', true) }}}; break;
- case 'glValidateProgram': ret = {{{ Functions.getIndex('_glValidateProgram', true) }}}; break;
- case 'glDepthFunc': ret = {{{ Functions.getIndex('_glDepthFunc', true) }}}; break;
- case 'glIsShader': ret = {{{ Functions.getIndex('_glIsShader', true) }}}; break;
- case 'glDepthMask': ret = {{{ Functions.getIndex('_glDepthMask', true) }}}; break;
- case 'glStencilMaskSeparate': ret = {{{ Functions.getIndex('_glStencilMaskSeparate', true) }}}; break;
- case 'glIsProgram': ret = {{{ Functions.getIndex('_glIsProgram', true) }}}; break;
- case 'glDisable': ret = {{{ Functions.getIndex('_glDisable', true) }}}; break;
- case 'glStencilOpSeparate': ret = {{{ Functions.getIndex('_glStencilOpSeparate', true) }}}; break;
- case 'glDrawArrays': ret = {{{ Functions.getIndex('_glDrawArrays', true) }}}; break;
- case 'glDrawElements': ret = {{{ Functions.getIndex('_glDrawElements', true) }}}; break;
- case 'glEnable': ret = {{{ Functions.getIndex('_glEnable', true) }}}; break;
- case 'glFinish': ret = {{{ Functions.getIndex('_glFinish', true) }}}; break;
- case 'glFlush': ret = {{{ Functions.getIndex('_glFlush', true) }}}; break;
- case 'glFrontFace': ret = {{{ Functions.getIndex('_glFrontFace', true) }}}; break;
- case 'glCullFace': ret = {{{ Functions.getIndex('_glCullFace', true) }}}; break;
- case 'glGenTextures': ret = {{{ Functions.getIndex('_glGenTextures', true) }}}; break;
- case 'glGetError': ret = {{{ Functions.getIndex('_glGetError', true) }}}; break;
- case 'glGetIntegerv': ret = {{{ Functions.getIndex('_glGetIntegerv', true) }}}; break;
- case 'glGetBooleanv': ret = {{{ Functions.getIndex('_glGetBooleanv', true) }}}; break;
- case 'glGetFloatv': ret = {{{ Functions.getIndex('_glGetFloatv', true) }}}; break;
- case 'glHint': ret = {{{ Functions.getIndex('_glHint', true) }}}; break;
- case 'glIsTexture': ret = {{{ Functions.getIndex('_glIsTexture', true) }}}; break;
- case 'glPixelStorei': ret = {{{ Functions.getIndex('_glPixelStorei', true) }}}; break;
- case 'glReadPixels': ret = {{{ Functions.getIndex('_glReadPixels', true) }}}; break;
- case 'glScissor': ret = {{{ Functions.getIndex('_glScissor', true) }}}; break;
- case 'glStencilFunc': ret = {{{ Functions.getIndex('_glStencilFunc', true) }}}; break;
- case 'glStencilMask': ret = {{{ Functions.getIndex('_glStencilMask', true) }}}; break;
- case 'glStencilOp': ret = {{{ Functions.getIndex('_glStencilOp', true) }}}; break;
- case 'glTexImage2D': ret = {{{ Functions.getIndex('_glTexImage2D', true) }}}; break;
- case 'glTexParameterf': ret = {{{ Functions.getIndex('_glTexParameterf', true) }}}; break;
- case 'glTexParameterfv': ret = {{{ Functions.getIndex('_glTexParameterfv', true) }}}; break;
- case 'glTexParameteri': ret = {{{ Functions.getIndex('_glTexParameteri', true) }}}; break;
- case 'glTexParameteriv': ret = {{{ Functions.getIndex('_glTexParameteriv', true) }}}; break;
- case 'glGetTexParameterfv': ret = {{{ Functions.getIndex('_glGetTexParameterfv', true) }}}; break;
- case 'glGetTexParameteriv': ret = {{{ Functions.getIndex('_glGetTexParameteriv', true) }}}; break;
- case 'glTexSubImage2D': ret = {{{ Functions.getIndex('_glTexSubImage2D', true) }}}; break;
- case 'glCopyTexImage2D': ret = {{{ Functions.getIndex('_glCopyTexImage2D', true) }}}; break;
- case 'glViewport': ret = {{{ Functions.getIndex('_glViewport', true) }}}; break;
- case 'glIsEnabled': ret = {{{ Functions.getIndex('_glIsEnabled', true) }}}; break;
- case 'glLineWidth': ret = {{{ Functions.getIndex('_glLineWidth', true) }}}; break;
- case 'glPolygonOffset': ret = {{{ Functions.getIndex('_glPolygonOffset', true) }}}; break;
- case 'glReleaseShaderCompiler': ret = {{{ Functions.getIndex('_glReleaseShaderCompiler', true) }}}; break;
- case 'glGetShaderPrecisionFormat': ret = {{{ Functions.getIndex('_glGetShaderPrecisionFormat', true) }}}; break;
- case 'glShaderBinary': ret = {{{ Functions.getIndex('_glShaderBinary', true) }}}; break;
+ case 'glIsRenderbuffer': ret = {{{ Functions.getIndex('_glIsRenderbuffer', true) }}}; break;
+ case 'glBlendEquation': ret = {{{ Functions.getIndex('_glBlendEquation', true) }}}; break;
+ case 'glBlendFunc': ret = {{{ Functions.getIndex('_glBlendFunc', true) }}}; break;
+ case 'glBlendFuncSeparate': ret = {{{ Functions.getIndex('_glBlendFuncSeparate', true) }}}; break;
+ case 'glBlendEquationSeparate': ret = {{{ Functions.getIndex('_glBlendEquationSeparate', true) }}}; break;
+ case 'glDepthRangef': ret = {{{ Functions.getIndex('_glDepthRangef', true) }}}; break;
+ case 'glClear': ret = {{{ Functions.getIndex('_glClear', true) }}}; break;
+ case 'glGenerateMipmap': ret = {{{ Functions.getIndex('_glGenerateMipmap', true) }}}; break;
+ case 'glBlendColor': ret = {{{ Functions.getIndex('_glBlendColor', true) }}}; break;
+ case 'glClearDepthf': ret = {{{ Functions.getIndex('_glClearDepthf', true) }}}; break;
+ case 'glDeleteProgram': ret = {{{ Functions.getIndex('_glDeleteProgram', true) }}}; break;
+ case 'glUniformMatrix3fv': ret = {{{ Functions.getIndex('_glUniformMatrix3fv', true) }}}; break;
+ case 'glClearColor': ret = {{{ Functions.getIndex('_glClearColor', true) }}}; break;
+ case 'glGetRenderbufferParameteriv': ret = {{{ Functions.getIndex('_glGetRenderbufferParameteriv', true) }}}; break;
+ case 'glGetShaderInfoLog': ret = {{{ Functions.getIndex('_glGetShaderInfoLog', true) }}}; break;
+ case 'glUniformMatrix4fv': ret = {{{ Functions.getIndex('_glUniformMatrix4fv', true) }}}; break;
+ case 'glClearStencil': ret = {{{ Functions.getIndex('_glClearStencil', true) }}}; break;
+ case 'glGetProgramInfoLog': ret = {{{ Functions.getIndex('_glGetProgramInfoLog', true) }}}; break;
+ case 'glGetUniformfv': ret = {{{ Functions.getIndex('_glGetUniformfv', true) }}}; break;
+ case 'glStencilFuncSeparate': ret = {{{ Functions.getIndex('_glStencilFuncSeparate', true) }}}; break;
+ case 'glSampleCoverage': ret = {{{ Functions.getIndex('_glSampleCoverage', true) }}}; break;
+ case 'glColorMask': ret = {{{ Functions.getIndex('_glColorMask', true) }}}; break;
+ case 'glGetShaderiv': ret = {{{ Functions.getIndex('_glGetShaderiv', true) }}}; break;
+ case 'glGetUniformiv': ret = {{{ Functions.getIndex('_glGetUniformiv', true) }}}; break;
+ case 'glCopyTexSubImage2D': ret = {{{ Functions.getIndex('_glCopyTexSubImage2D', true) }}}; break;
+ case 'glDetachShader': ret = {{{ Functions.getIndex('_glDetachShader', true) }}}; break;
+ case 'glGetShaderSource': ret = {{{ Functions.getIndex('_glGetShaderSource', true) }}}; break;
+ case 'glDeleteTextures': ret = {{{ Functions.getIndex('_glDeleteTextures', true) }}}; break;
+ case 'glGetAttachedShaders': ret = {{{ Functions.getIndex('_glGetAttachedShaders', true) }}}; break;
+ case 'glValidateProgram': ret = {{{ Functions.getIndex('_glValidateProgram', true) }}}; break;
+ case 'glDepthFunc': ret = {{{ Functions.getIndex('_glDepthFunc', true) }}}; break;
+ case 'glIsShader': ret = {{{ Functions.getIndex('_glIsShader', true) }}}; break;
+ case 'glDepthMask': ret = {{{ Functions.getIndex('_glDepthMask', true) }}}; break;
+ case 'glStencilMaskSeparate': ret = {{{ Functions.getIndex('_glStencilMaskSeparate', true) }}}; break;
+ case 'glIsProgram': ret = {{{ Functions.getIndex('_glIsProgram', true) }}}; break;
+ case 'glDisable': ret = {{{ Functions.getIndex('_glDisable', true) }}}; break;
+ case 'glStencilOpSeparate': ret = {{{ Functions.getIndex('_glStencilOpSeparate', true) }}}; break;
+ case 'glDrawArrays': ret = {{{ Functions.getIndex('_glDrawArrays', true) }}}; break;
+ case 'glDrawElements': ret = {{{ Functions.getIndex('_glDrawElements', true) }}}; break;
+ case 'glEnable': ret = {{{ Functions.getIndex('_glEnable', true) }}}; break;
+ case 'glFinish': ret = {{{ Functions.getIndex('_glFinish', true) }}}; break;
+ case 'glFlush': ret = {{{ Functions.getIndex('_glFlush', true) }}}; break;
+ case 'glFrontFace': ret = {{{ Functions.getIndex('_glFrontFace', true) }}}; break;
+ case 'glCullFace': ret = {{{ Functions.getIndex('_glCullFace', true) }}}; break;
+ case 'glGenTextures': ret = {{{ Functions.getIndex('_glGenTextures', true) }}}; break;
+ case 'glGetError': ret = {{{ Functions.getIndex('_glGetError', true) }}}; break;
+ case 'glGetIntegerv': ret = {{{ Functions.getIndex('_glGetIntegerv', true) }}}; break;
+ case 'glGetBooleanv': ret = {{{ Functions.getIndex('_glGetBooleanv', true) }}}; break;
+ case 'glGetFloatv': ret = {{{ Functions.getIndex('_glGetFloatv', true) }}}; break;
+ case 'glHint': ret = {{{ Functions.getIndex('_glHint', true) }}}; break;
+ case 'glIsTexture': ret = {{{ Functions.getIndex('_glIsTexture', true) }}}; break;
+ case 'glPixelStorei': ret = {{{ Functions.getIndex('_glPixelStorei', true) }}}; break;
+ case 'glReadPixels': ret = {{{ Functions.getIndex('_glReadPixels', true) }}}; break;
+ case 'glScissor': ret = {{{ Functions.getIndex('_glScissor', true) }}}; break;
+ case 'glStencilFunc': ret = {{{ Functions.getIndex('_glStencilFunc', true) }}}; break;
+ case 'glStencilMask': ret = {{{ Functions.getIndex('_glStencilMask', true) }}}; break;
+ case 'glStencilOp': ret = {{{ Functions.getIndex('_glStencilOp', true) }}}; break;
+ case 'glTexImage2D': ret = {{{ Functions.getIndex('_glTexImage2D', true) }}}; break;
+ case 'glTexParameterf': ret = {{{ Functions.getIndex('_glTexParameterf', true) }}}; break;
+ case 'glTexParameterfv': ret = {{{ Functions.getIndex('_glTexParameterfv', true) }}}; break;
+ case 'glTexParameteri': ret = {{{ Functions.getIndex('_glTexParameteri', true) }}}; break;
+ case 'glTexParameteriv': ret = {{{ Functions.getIndex('_glTexParameteriv', true) }}}; break;
+ case 'glGetTexParameterfv': ret = {{{ Functions.getIndex('_glGetTexParameterfv', true) }}}; break;
+ case 'glGetTexParameteriv': ret = {{{ Functions.getIndex('_glGetTexParameteriv', true) }}}; break;
+ case 'glTexSubImage2D': ret = {{{ Functions.getIndex('_glTexSubImage2D', true) }}}; break;
+ case 'glCopyTexImage2D': ret = {{{ Functions.getIndex('_glCopyTexImage2D', true) }}}; break;
+ case 'glViewport': ret = {{{ Functions.getIndex('_glViewport', true) }}}; break;
+ case 'glIsEnabled': ret = {{{ Functions.getIndex('_glIsEnabled', true) }}}; break;
+ case 'glLineWidth': ret = {{{ Functions.getIndex('_glLineWidth', true) }}}; break;
+ case 'glPolygonOffset': ret = {{{ Functions.getIndex('_glPolygonOffset', true) }}}; break;
+ case 'glReleaseShaderCompiler': ret = {{{ Functions.getIndex('_glReleaseShaderCompiler', true) }}}; break;
+ case 'glGetShaderPrecisionFormat': ret = {{{ Functions.getIndex('_glGetShaderPrecisionFormat', true) }}}; break;
+ case 'glShaderBinary': ret = {{{ Functions.getIndex('_glShaderBinary', true) }}}; break;
}
if (!ret) Module.printErr('WARNING: getProcAddress failed for ' + name);
return ret;
@@ -1960,10 +1990,879 @@ var LibraryGL = {
// GL Immediate mode
+ // See comment in GLEmulation.init()
+#if FULL_ES2 == 0
$GLImmediate__postset: 'GL.immediate.setupFuncs(); Browser.moduleContextCreatedCallbacks.push(function() { GL.immediate.init() });',
+#endif
$GLImmediate__deps: ['$Browser', '$GL', '$GLEmulation'],
$GLImmediate: {
- MAX_TEXTURES: 7,
+ MapTreeLib: null,
+ spawnMapTreeLib: function() {
+ /* A naive implementation of a map backed by an array, and accessed by
+ * naive iteration along the array. (hashmap with only one bucket)
+ */
+ function CNaiveListMap() {
+ var list = [];
+
+ this.insert = function(key, val) {
+ if (this.contains(key|0)) return false;
+ list.push([key, val]);
+ return true;
+ };
+
+ var __contains_i;
+ this.contains = function(key) {
+ for (__contains_i = 0; __contains_i < list.length; ++__contains_i) {
+ if (list[__contains_i][0] === key) return true;
+ }
+ return false;
+ };
+
+ var __get_i;
+ this.get = function(key) {
+ for (__get_i = 0; __get_i < list.length; ++__get_i) {
+ if (list[__get_i][0] === key) return list[__get_i][1];
+ }
+ return undefined;
+ };
+ };
+
+ /* A tree of map nodes.
+ Uses `KeyView`s to allow descending the tree without garbage.
+ Example: {
+ // Create our map object.
+ var map = new ObjTreeMap();
+
+ // Grab the static keyView for the map.
+ var keyView = map.GetStaticKeyView();
+
+ // Let's make a map for:
+ // root: <undefined>
+ // 1: <undefined>
+ // 2: <undefined>
+ // 5: "Three, sir!"
+ // 3: "Three!"
+
+ // Note how we can chain together `Reset` and `Next` to
+ // easily descend based on multiple key fragments.
+ keyView.Reset().Next(1).Next(2).Next(5).Set("Three, sir!");
+ keyView.Reset().Next(1).Next(2).Next(3).Set("Three!");
+ }
+ */
+ function CMapTree() {
+ function CNLNode() {
+ var map = new CNaiveListMap();
+
+ this.child = function(keyFrag) {
+ if (!map.contains(keyFrag|0)) {
+ map.insert(keyFrag|0, new CNLNode());
+ }
+ return map.get(keyFrag|0);
+ };
+
+ this.value = undefined;
+ this.get = function() {
+ return this.value;
+ };
+
+ this.set = function(val) {
+ this.value = val;
+ };
+ }
+
+ function CKeyView(root) {
+ var cur;
+
+ this.reset = function() {
+ cur = root;
+ return this;
+ };
+ this.reset();
+
+ this.next = function(keyFrag) {
+ cur = cur.child(keyFrag);
+ return this;
+ };
+
+ this.get = function() {
+ return cur.get();
+ };
+
+ this.set = function(val) {
+ cur.set(val);
+ };
+ };
+
+ var root;
+ var staticKeyView;
+
+ this.createKeyView = function() {
+ return new CKeyView(root);
+ }
+
+ this.clear = function() {
+ root = new CNLNode();
+ staticKeyView = this.createKeyView();
+ };
+ this.clear();
+
+ this.getStaticKeyView = function() {
+ staticKeyView.reset();
+ return staticKeyView;
+ };
+ };
+
+ // Exports:
+ return {
+ create: function() {
+ return new CMapTree();
+ },
+ };
+ },
+
+ TexEnvJIT: null,
+ spawnTexEnvJIT: function() {
+ // GL defs:
+ var GL_TEXTURE0 = 0x84C0;
+ var GL_TEXTURE_1D = 0x0DE0;
+ var GL_TEXTURE_2D = 0x0DE1;
+ var GL_TEXTURE_3D = 0x806f;
+ var GL_TEXTURE_CUBE_MAP = 0x8513;
+ var GL_TEXTURE_ENV = 0x2300;
+ var GL_TEXTURE_ENV_MODE = 0x2200;
+ var GL_TEXTURE_ENV_COLOR = 0x2201;
+ var GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+ var GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+ var GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+ var GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+ var GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+ var GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+
+ var GL_SRC0_RGB = 0x8580;
+ var GL_SRC1_RGB = 0x8581;
+ var GL_SRC2_RGB = 0x8582;
+
+ var GL_SRC0_ALPHA = 0x8588;
+ var GL_SRC1_ALPHA = 0x8589;
+ var GL_SRC2_ALPHA = 0x858A;
+
+ var GL_OPERAND0_RGB = 0x8590;
+ var GL_OPERAND1_RGB = 0x8591;
+ var GL_OPERAND2_RGB = 0x8592;
+
+ var GL_OPERAND0_ALPHA = 0x8598;
+ var GL_OPERAND1_ALPHA = 0x8599;
+ var GL_OPERAND2_ALPHA = 0x859A;
+
+ var GL_COMBINE_RGB = 0x8571;
+ var GL_COMBINE_ALPHA = 0x8572;
+
+ var GL_RGB_SCALE = 0x8573;
+ var GL_ALPHA_SCALE = 0x0D1C;
+
+ // env.mode
+ var GL_ADD = 0x0104;
+ var GL_BLEND = 0x0BE2;
+ var GL_REPLACE = 0x1E01;
+ var GL_MODULATE = 0x2100;
+ var GL_DECAL = 0x2101;
+ var GL_COMBINE = 0x8570;
+
+ // env.color/alphaCombiner
+ //var GL_ADD = 0x0104;
+ //var GL_REPLACE = 0x1E01;
+ //var GL_MODULATE = 0x2100;
+ var GL_SUBTRACT = 0x84E7;
+ var GL_INTERPOLATE = 0x8575;
+
+ // env.color/alphaSrc
+ var GL_TEXTURE = 0x1702;
+ var GL_CONSTANT = 0x8576;
+ var GL_PRIMARY_COLOR = 0x8577;
+ var GL_PREVIOUS = 0x8578;
+
+ // env.color/alphaOp
+ var GL_SRC_COLOR = 0x0300;
+ var GL_ONE_MINUS_SRC_COLOR = 0x0301;
+ var GL_SRC_ALPHA = 0x0302;
+ var GL_ONE_MINUS_SRC_ALPHA = 0x0303;
+
+ var GL_RGB = 0x1907;
+ var GL_RGBA = 0x1908;
+
+ // Our defs:
+ var TEXENVJIT_NAMESPACE_PREFIX = "tej_";
+ // Not actually constant, as they can be changed between JIT passes:
+ var TEX_UNIT_UNIFORM_PREFIX = "uTexUnit";
+ var TEX_COORD_VARYING_PREFIX = "vTexCoord";
+ var PRIM_COLOR_VARYING = "vPrimColor";
+ var TEX_MATRIX_UNIFORM_PREFIX = "uTexMatrix";
+
+ // Static vars:
+ var s_texUnits = null; //[];
+ var s_activeTexture = 0;
+
+ var s_requiredTexUnitsForPass = [];
+
+ // Static funcs:
+ function abort(info) {
+ assert(false, "[TexEnvJIT] ABORT: " + info);
+ }
+
+ function abort_noSupport(info) {
+ abort("No support: " + info);
+ }
+
+ function abort_sanity(info) {
+ abort("Sanity failure: " + info);
+ }
+
+ function genTexUnitSampleExpr(texUnitID) {
+ var texUnit = s_texUnits[texUnitID];
+ var texType = texUnit.getTexType();
+
+ var func = null;
+ switch (texType) {
+ case GL_TEXTURE_1D:
+ func = "texture2D";
+ break;
+ case GL_TEXTURE_2D:
+ func = "texture2D";
+ break;
+ case GL_TEXTURE_3D:
+ return abort_noSupport("No support for 3D textures.");
+ case GL_TEXTURE_CUBE_MAP:
+ func = "textureCube";
+ break;
+ default:
+ return abort_sanity("Unknown texType: 0x" + texType.toString(16));
+ }
+
+ var texCoordExpr = TEX_COORD_VARYING_PREFIX + texUnitID;
+ if (TEX_MATRIX_UNIFORM_PREFIX != null) {
+ texCoordExpr = "(" + TEX_MATRIX_UNIFORM_PREFIX + texUnitID + " * " + texCoordExpr + ")";
+ }
+ return func + "(" + TEX_UNIT_UNIFORM_PREFIX + texUnitID + ", " + texCoordExpr + ".xy)";
+ }
+
+ function getTypeFromCombineOp(op) {
+ switch (op) {
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ return "vec3";
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ return "float";
+ }
+
+ return Abort_NoSupport("Unsupported combiner op: 0x" + op.toString(16));
+ }
+
+ function getCurTexUnit() {
+ return s_texUnits[s_activeTexture];
+ }
+
+ function genCombinerSourceExpr(texUnitID, constantExpr, previousVar,
+ src, op)
+ {
+ var srcExpr = null;
+ switch (src) {
+ case GL_TEXTURE:
+ srcExpr = genTexUnitSampleExpr(texUnitID);
+ break;
+ case GL_CONSTANT:
+ srcExpr = constantExpr;
+ break;
+ case GL_PRIMARY_COLOR:
+ srcExpr = PRIM_COLOR_VARYING;
+ break;
+ case GL_PREVIOUS:
+ srcExpr = previousVar;
+ break;
+ default:
+ return abort_noSupport("Unsupported combiner src: 0x" + src.toString(16));
+ }
+
+ var expr = null;
+ switch (op) {
+ case GL_SRC_COLOR:
+ expr = srcExpr + ".rgb";
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ expr = "(vec3(1.0) - " + srcExpr + ".rgb)";
+ break;
+ case GL_SRC_ALPHA:
+ expr = srcExpr + ".a";
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ expr = "(1.0 - " + srcExpr + ".a)";
+ break;
+ default:
+ return abort_noSupport("Unsupported combiner op: 0x" + op.toString(16));
+ }
+
+ return expr;
+ }
+
+ function valToFloatLiteral(val) {
+ if (val == Math.round(val)) return val + '.0';
+ return val;
+ }
+
+
+ // Classes:
+ function CTexEnv() {
+ this.mode = GL_MODULATE;
+ this.colorCombiner = GL_MODULATE;
+ this.alphaCombiner = GL_MODULATE;
+ this.colorScale = 1;
+ this.alphaScale = 1;
+ this.envColor = [0, 0, 0, 0];
+
+ this.colorSrc = [
+ GL_TEXTURE,
+ GL_PREVIOUS,
+ GL_CONSTANT
+ ];
+ this.alphaSrc = [
+ GL_TEXTURE,
+ GL_PREVIOUS,
+ GL_CONSTANT
+ ];
+ this.colorOp = [
+ GL_SRC_COLOR,
+ GL_SRC_COLOR,
+ GL_SRC_ALPHA
+ ];
+ this.alphaOp = [
+ GL_SRC_ALPHA,
+ GL_SRC_ALPHA,
+ GL_SRC_ALPHA
+ ];
+
+ this.traverseState = function(keyView) {
+ keyView.next(this.mode);
+ keyView.next(this.colorCombiner);
+ keyView.next(this.alphaCombiner);
+ keyView.next(this.colorCombiner);
+ keyView.next(this.alphaScale);
+ keyView.next(this.envColor[0]);
+ keyView.next(this.envColor[1]);
+ keyView.next(this.envColor[2]);
+ keyView.next(this.envColor[3]);
+
+ keyView.next(this.colorSrc[0]);
+ keyView.next(this.colorSrc[1]);
+ keyView.next(this.colorSrc[2]);
+
+ keyView.next(this.alphaSrc[0]);
+ keyView.next(this.alphaSrc[1]);
+ keyView.next(this.alphaSrc[2]);
+
+ keyView.next(this.colorOp[0]);
+ keyView.next(this.colorOp[1]);
+ keyView.next(this.colorOp[2]);
+
+ keyView.next(this.alphaOp[0]);
+ keyView.next(this.alphaOp[1]);
+ keyView.next(this.alphaOp[2]);
+ };
+ }
+
+ function CTexUnit() {
+ this.env = new CTexEnv();
+ this.enabled_tex1D = false;
+ this.enabled_tex2D = false;
+ this.enabled_tex3D = false;
+ this.enabled_texCube = false;
+
+ this.traverseState = function(keyView) {
+ var texUnitType = this.getTexType();
+ keyView.next(texUnitType);
+ if (!texUnitType) return;
+ this.env.traverseState(keyView);
+ };
+ };
+
+ // Class impls:
+ CTexUnit.prototype.enabled = function() {
+ return this.getTexType() != 0;
+ }
+
+ CTexUnit.prototype.genPassLines = function(passOutputVar, passInputVar, texUnitID) {
+ if (!this.enabled()) {
+ return ["vec4 " + passOutputVar + " = " + passInputVar + ";"];
+ }
+
+ return this.env.genPassLines(passOutputVar, passInputVar, texUnitID);
+ }
+
+ CTexUnit.prototype.getTexType = function() {
+ if (this.enabled_texCube) {
+ return GL_TEXTURE_CUBE_MAP;
+ } else if (this.enabled_tex3D) {
+ return GL_TEXTURE_3D;
+ } else if (this.enabled_tex2D) {
+ return GL_TEXTURE_2D;
+ } else if (this.enabled_tex1D) {
+ return GL_TEXTURE_1D;
+ }
+ return 0;
+ }
+
+ CTexEnv.prototype.genPassLines = function(passOutputVar, passInputVar, texUnitID) {
+ switch (this.mode) {
+ case GL_REPLACE: {
+ /* RGB:
+ * Cv = Cs
+ * Av = Ap // Note how this is different, and that we'll
+ * need to track the bound texture internalFormat
+ * to get this right.
+ *
+ * RGBA:
+ * Cv = Cs
+ * Av = As
+ */
+ return [
+ "vec4 " + passOutputVar + " = " + genTexUnitSampleExpr(texUnitID) + ";",
+ ];
+ }
+ case GL_ADD: {
+ /* RGBA:
+ * Cv = Cp + Cs
+ * Av = ApAs
+ */
+ var prefix = TEXENVJIT_NAMESPACE_PREFIX + 'env' + texUnitID + "_";
+ var texVar = prefix + "tex";
+ var colorVar = prefix + "color";
+ var alphaVar = prefix + "alpha";
+
+ return [
+ "vec4 " + texVar + " = " + genTexUnitSampleExpr(texUnitID) + ";",
+ "vec3 " + colorVar + " = " + passInputVar + ".rgb + " + texVar + ".rgb;",
+ "float " + alphaVar + " = " + passInputVar + ".a * " + texVar + ".a;",
+ "vec4 " + passOutputVar + " = vec4(" + colorVar + ", " + alphaVar + ");",
+ ];
+ }
+ case GL_MODULATE: {
+ /* RGBA:
+ * Cv = CpCs
+ * Av = ApAs
+ */
+ var line = [
+ "vec4 " + passOutputVar,
+ " = ",
+ passInputVar,
+ " * ",
+ genTexUnitSampleExpr(texUnitID),
+ ";",
+ ];
+ return [line.join("")];
+ }
+ case GL_DECAL: {
+ /* RGBA:
+ * Cv = Cp(1 - As) + CsAs
+ * Av = Ap
+ */
+ var prefix = TEXENVJIT_NAMESPACE_PREFIX + 'env' + texUnitID + "_";
+ var texVar = prefix + "tex";
+ var colorVar = prefix + "color";
+ var alphaVar = prefix + "alpha";
+
+ return [
+ "vec4 " + texVar + " = " + genTexUnitSampleExpr(texUnitID) + ";",
+ [
+ "vec3 " + colorVar + " = ",
+ passInputVar + ".rgb * (1.0 - " + texVar + ".a)",
+ " + ",
+ texVar + ".rgb * " + texVar + ".a",
+ ";"
+ ].join(""),
+ "float " + alphaVar + " = " + passInputVar + ".a;",
+ "vec4 " + passOutputVar + " = vec4(" + colorVar + ", " + alphaVar + ");",
+ ];
+ }
+ case GL_BLEND: {
+ /* RGBA:
+ * Cv = Cp(1 - Cs) + CcCs
+ * Av = As
+ */
+ var prefix = TEXENVJIT_NAMESPACE_PREFIX + 'env' + texUnitID + "_";
+ var texVar = prefix + "tex";
+ var colorVar = prefix + "color";
+ var alphaVar = prefix + "alpha";
+
+ return [
+ "vec4 " + texVar + " = " + genTexUnitSampleExpr(texUnitID) + ";",
+ [
+ "vec3 " + colorVar + " = ",
+ passInputVar + ".rgb * (1.0 - " + texVar + ".rgb)",
+ " + ",
+ PRIM_COLOR_VARYING + ".rgb * " + texVar + ".rgb",
+ ";"
+ ].join(""),
+ "float " + alphaVar + " = " + texVar + ".a;",
+ "vec4 " + passOutputVar + " = vec4(" + colorVar + ", " + alphaVar + ");",
+ ];
+ }
+ case GL_COMBINE: {
+ var prefix = TEXENVJIT_NAMESPACE_PREFIX + 'env' + texUnitID + "_";
+ var colorVar = prefix + "color";
+ var alphaVar = prefix + "alpha";
+ var colorLines = this.genCombinerLines(true, colorVar,
+ passInputVar, texUnitID,
+ this.colorCombiner, this.colorSrc, this.colorOp);
+ var alphaLines = this.genCombinerLines(false, alphaVar,
+ passInputVar, texUnitID,
+ this.alphaCombiner, this.alphaSrc, this.alphaOp);
+ var line = [
+ "vec4 " + passOutputVar,
+ " = ",
+ "vec4(",
+ colorVar + " * " + valToFloatLiteral(this.colorScale),
+ ", ",
+ alphaVar + " * " + valToFloatLiteral(this.alphaScale),
+ ")",
+ ";",
+ ].join("");
+ return [].concat(colorLines, alphaLines, [line]);
+ }
+ }
+
+ return Abort_NoSupport("Unsupported TexEnv mode: 0x" + this.mode.toString(16));
+ }
+
+ CTexEnv.prototype.genCombinerLines = function(isColor, outputVar,
+ passInputVar, texUnitID,
+ combiner, srcArr, opArr)
+ {
+ var argsNeeded = null;
+ switch (combiner) {
+ case GL_REPLACE:
+ argsNeeded = 1;
+ break;
+
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_SUBTRACT:
+ argsNeeded = 2;
+ break;
+
+ case GL_INTERPOLATE:
+ argsNeeded = 3;
+ break;
+
+ default:
+ return abort_noSupport("Unsupported combiner: 0x" + combiner.toString(16));
+ }
+
+ var constantExpr = [
+ "vec4(",
+ valToFloatLiteral(this.envColor[0]),
+ ", ",
+ valToFloatLiteral(this.envColor[1]),
+ ", ",
+ valToFloatLiteral(this.envColor[2]),
+ ", ",
+ valToFloatLiteral(this.envColor[3]),
+ ")",
+ ].join("");
+ var src0Expr = (argsNeeded >= 1) ? genCombinerSourceExpr(texUnitID, constantExpr, passInputVar, srcArr[0], opArr[0])
+ : null;
+ var src1Expr = (argsNeeded >= 2) ? genCombinerSourceExpr(texUnitID, constantExpr, passInputVar, srcArr[1], opArr[1])
+ : null;
+ var src2Expr = (argsNeeded >= 3) ? genCombinerSourceExpr(texUnitID, constantExpr, passInputVar, srcArr[2], opArr[2])
+ : null;
+
+ var outputType = isColor ? "vec3" : "float";
+ var lines = null;
+ switch (combiner) {
+ case GL_REPLACE: {
+ var line = [
+ outputType + " " + outputVar,
+ " = ",
+ src0Expr,
+ ";",
+ ];
+ lines = [line.join("")];
+ break;
+ }
+ case GL_MODULATE: {
+ var line = [
+ outputType + " " + outputVar + " = ",
+ src0Expr + " * " + src1Expr,
+ ";",
+ ];
+ lines = [line.join("")];
+ break;
+ }
+ case GL_ADD: {
+ var line = [
+ outputType + " " + outputVar + " = ",
+ src0Expr + " + " + src1Expr,
+ ";",
+ ];
+ lines = [line.join("")];
+ break;
+ }
+ case GL_SUBTRACT: {
+ var line = [
+ outputType + " " + outputVar + " = ",
+ src0Expr + " - " + src1Expr,
+ ";",
+ ];
+ lines = [line.join("")];
+ break;
+ }
+ case GL_INTERPOLATE: {
+ var prefix = TEXENVJIT_NAMESPACE_PREFIX + 'env' + texUnitID + "_";
+ var arg2Var = prefix + "colorSrc2";
+ var arg2Line = getTypeFromCombineOp(this.colorOp[2]) + " " + arg2Var + " = " + src2Expr + ";";
+
+ var line = [
+ outputType + " " + outputVar,
+ " = ",
+ src0Expr + " * " + arg2Var,
+ " + ",
+ src1Expr + " * (1.0 - " + arg2Var + ")",
+ ";",
+ ];
+ lines = [
+ arg2Line,
+ line.join(""),
+ ];
+ break;
+ }
+
+ default:
+ return abort_sanity("Unmatched TexEnv.colorCombiner?");
+ }
+
+ return lines;
+ }
+
+ return {
+ // Exports:
+ init: function(gl, specifiedMaxTextureImageUnits) {
+ var maxTexUnits = 0;
+ if (specifiedMaxTextureImageUnits) {
+ maxTexUnits = specifiedMaxTextureImageUnits;
+ } else if (gl) {
+ maxTexUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
+ }
+
+ assert(maxTexUnits > 0);
+
+ s_texUnits = [];
+ for (var i = 0; i < maxTexUnits; i++) {
+ s_texUnits.push(new CTexUnit());
+ }
+ },
+
+ setGLSLVars: function(uTexUnitPrefix, vTexCoordPrefix, vPrimColor, uTexMatrixPrefix) {
+ TEX_UNIT_UNIFORM_PREFIX = uTexUnitPrefix;
+ TEX_COORD_VARYING_PREFIX = vTexCoordPrefix;
+ PRIM_COLOR_VARYING = vPrimColor;
+ TEX_MATRIX_UNIFORM_PREFIX = uTexMatrixPrefix;
+ },
+
+ genAllPassLines: function(resultDest, indentSize) {
+ indentSize = indentSize || 0;
+
+ s_requiredTexUnitsForPass.length = 0; // Clear the list.
+ var lines = [];
+ var lastPassVar = PRIM_COLOR_VARYING;
+ for (var i = 0; i < s_texUnits.length; i++) {
+ if (!s_texUnits[i].enabled()) continue;
+
+ s_requiredTexUnitsForPass.push(i);
+
+ var prefix = TEXENVJIT_NAMESPACE_PREFIX + 'env' + i + "_";
+ var passOutputVar = prefix + "result";
+
+ var newLines = s_texUnits[i].genPassLines(passOutputVar, lastPassVar, i);
+ lines = lines.concat(newLines, [""]);
+
+ lastPassVar = passOutputVar;
+ }
+ lines.push(resultDest + " = " + lastPassVar + ";");
+
+ var indent = "";
+ for (var i = 0; i < indentSize; i++) indent += " ";
+
+ var output = indent + lines.join("\n" + indent);
+
+ return output;
+ },
+
+ getUsedTexUnitList: function() {
+ return s_requiredTexUnitsForPass;
+ },
+
+ traverseState: function(keyView) {
+ for (var i = 0; i < s_texUnits.length; i++) {
+ var texUnit = s_texUnits[i];
+ var enabled = texUnit.enabled();
+ keyView.next(enabled);
+ if (enabled) {
+ texUnit.traverseState(keyView);
+ }
+ }
+ },
+
+ getTexUnitType: function(texUnitID) {
+ assert(texUnitID >= 0 &&
+ texUnitID < s_texUnits.length);
+
+ return s_texUnits[texUnitID].getTexType();
+ },
+
+ // Hooks:
+ hook_activeTexture: function(texture) {
+ s_activeTexture = texture - GL_TEXTURE0;
+ },
+
+ hook_enable: function(cap) {
+ var cur = getCurTexUnit();
+ switch (cap) {
+ case GL_TEXTURE_1D:
+ cur.enabled_tex1D = true;
+ break;
+ case GL_TEXTURE_2D:
+ cur.enabled_tex2D = true;
+ break;
+ case GL_TEXTURE_3D:
+ cur.enabled_tex3D = true;
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ cur.enabled_texCube = true;
+ break;
+ }
+ },
+
+ hook_disable: function(cap) {
+ var cur = getCurTexUnit();
+ switch (cap) {
+ case GL_TEXTURE_1D:
+ cur.enabled_tex1D = false;
+ break;
+ case GL_TEXTURE_2D:
+ cur.enabled_tex2D = false;
+ break;
+ case GL_TEXTURE_3D:
+ cur.enabled_tex3D = false;
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ cur.enabled_texCube = false;
+ break;
+ }
+ },
+
+ hook_texEnvf: function(target, pname, param) {
+ if (target != GL_TEXTURE_ENV)
+ return;
+
+ var env = getCurTexUnit().env;
+ switch (pname) {
+ case GL_RGB_SCALE:
+ env.colorScale = param;
+ break;
+ case GL_ALPHA_SCALE:
+ env.alphaScale = param;
+ break;
+
+ default:
+ Module.printErr('WARNING: Unhandled `pname` in call to `glTexEnvf`.');
+ }
+ },
+
+ hook_texEnvi: function(target, pname, param) {
+ if (target != GL_TEXTURE_ENV)
+ return;
+
+ var env = getCurTexUnit().env;
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ env.mode = param;
+ break;
+
+ case GL_COMBINE_RGB:
+ env.colorCombiner = param;
+ break;
+ case GL_COMBINE_ALPHA:
+ env.alphaCombiner = param;
+ break;
+
+ case GL_SRC0_RGB:
+ env.colorSrc[0] = param;
+ break;
+ case GL_SRC1_RGB:
+ env.colorSrc[1] = param;
+ break;
+ case GL_SRC2_RGB:
+ env.colorSrc[2] = param;
+ break;
+
+ case GL_SRC0_ALPHA:
+ env.alphaSrc[0] = param;
+ break;
+ case GL_SRC1_ALPHA:
+ env.alphaSrc[1] = param;
+ break;
+ case GL_SRC2_ALPHA:
+ env.alphaSrc[2] = param;
+ break;
+
+ case GL_OPERAND0_RGB:
+ env.colorOp[0] = param;
+ break;
+ case GL_OPERAND1_RGB:
+ env.colorOp[1] = param;
+ break;
+ case GL_OPERAND2_RGB:
+ env.colorOp[2] = param;
+ break;
+
+ case GL_OPERAND0_ALPHA:
+ env.alphaOp[0] = param;
+ break;
+ case GL_OPERAND1_ALPHA:
+ env.alphaOp[1] = param;
+ break;
+ case GL_OPERAND2_ALPHA:
+ env.alphaOp[2] = param;
+ break;
+
+ case GL_RGB_SCALE:
+ env.colorScale = param;
+ break;
+ case GL_ALPHA_SCALE:
+ env.alphaScale = param;
+ break;
+
+ default:
+ Module.printErr('WARNING: Unhandled `pname` in call to `glTexEnvi`.');
+ }
+ },
+
+ hook_texEnvfv: function(target, pname, params) {
+ if (target != GL_TEXTURE_ENV) return;
+
+ var env = getCurTexUnit().env;
+ switch (pname) {
+ case GL_TEXTURE_ENV_COLOR: {
+ for (var i = 0; i < 4; i++) {
+ var param = {{{ makeGetValue('params', 'i*4', 'float') }}};
+ env.envColor[i] = param;
+ }
+ break
+ }
+ default:
+ Module.printErr('WARNING: Unhandled `pname` in call to `glTexEnvfv`.');
+ }
+ },
+ };
+ },
// Vertex and index data
vertexData: null, // current vertex data. either tempData (glBegin etc.) or a view into the heap (gl*Pointer). Default view is F32
@@ -1974,7 +2873,6 @@ var LibraryGL = {
mode: -1,
rendererCache: null,
- rendererCacheItemTemplate: [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null], // 16 nulls
rendererComponents: [], // small cache for calls inside glBegin/end. counts how many times the element was seen
rendererComponentPointer: 0, // next place to start a glBegin/end component
lastRenderer: null, // used to avoid cleaning up and re-preparing the same renderer
@@ -1988,6 +2886,7 @@ var LibraryGL = {
currentMatrix: 'm', // default is modelview
tempMatrix: null,
matricesModified: false,
+ useTextureMatrix: false,
// Clientside attributes
VERTEX: 0,
@@ -2000,8 +2899,8 @@ var LibraryGL = {
TEXTURE4: 7,
TEXTURE5: 8,
TEXTURE6: 9,
- NUM_ATTRIBUTES: 10,
- NUM_TEXTURES: 7,
+ NUM_ATTRIBUTES: 10, // Overwritten in init().
+ MAX_TEXTURES: 7, // Overwritten in init().
totalEnabledClientAttributes: 0,
enabledClientAttributes: [0, 0],
@@ -2010,6 +2909,8 @@ var LibraryGL = {
modifiedClientAttributes: false,
clientActiveTexture: 0,
clientColor: null,
+ usedTexUnitList: [],
+ fixedFunctionProgram: null,
setClientAttribute: function(name, size, type, stride, pointer) {
var attrib = this.clientAttributes[name];
@@ -2042,7 +2943,9 @@ var LibraryGL = {
if (!this.rendererComponents[name]) {
this.rendererComponents[name] = 1;
#if ASSERTIONS
- assert(!this.enabledClientAttributes[name]); // cannot get mixed up with this, for example we will disable this later
+ if (this.enabledClientAttributes[name]) {
+ console.log("Warning: glTexCoord used after EnableClientState for TEXTURE_COORD_ARRAY for TEXTURE0. Disabling TEXTURE_COORD_ARRAY...");
+ }
#endif
this.enabledClientAttributes[name] = true;
this.setClientAttribute(name, size, type, 0, this.rendererComponentPointer);
@@ -2062,19 +2965,18 @@ var LibraryGL = {
// return a renderer object given the liveClientAttributes
// we maintain a cache of renderers, optimized to not generate garbage
var attributes = GL.immediate.liveClientAttributes;
- var cacheItem = GL.immediate.rendererCache;
+ var cacheMap = GL.immediate.rendererCache;
var temp;
+ var keyView = cacheMap.getStaticKeyView().reset();
+
+ // By attrib state:
for (var i = 0; i < attributes.length; i++) {
var attribute = attributes[i];
- temp = cacheItem[attribute.name];
- cacheItem = temp ? temp : (cacheItem[attribute.name] = GL.immediate.rendererCacheItemTemplate.slice());
- temp = cacheItem[attribute.size];
- cacheItem = temp ? temp : (cacheItem[attribute.size] = GL.immediate.rendererCacheItemTemplate.slice());
- var typeIndex = attribute.type - GL.byteSizeByTypeRoot; // ensure it starts at 0 to keep the cache items dense
- temp = cacheItem[typeIndex];
- cacheItem = temp ? temp : (cacheItem[typeIndex] = GL.immediate.rendererCacheItemTemplate.slice());
- }
- var fogParam;
+ keyView.next(attribute.name).next(attribute.size).next(attribute.type);
+ }
+
+ // By fog state:
+ var fogParam = 0;
if (GLEmulation.fogEnabled) {
switch (GLEmulation.fogMode) {
case 0x0801: // GL_EXP2
@@ -2087,33 +2989,40 @@ var LibraryGL = {
fogParam = 3;
break;
}
- } else {
- fogParam = 0;
}
- temp = cacheItem[fogParam];
- cacheItem = temp ? temp : (cacheItem[fogParam] = GL.immediate.rendererCacheItemTemplate.slice());
- if (GL.currProgram) { // Note the order here; this one is last, and optional. Note that we cannot ensure it is dense, sadly
- temp = cacheItem[GL.currProgram];
- cacheItem = temp ? temp : (cacheItem[GL.currProgram] = GL.immediate.rendererCacheItemTemplate.slice());
+ keyView.next(fogParam);
+
+ // By cur program:
+ keyView.next(GL.currProgram);
+ if (!GL.currProgram) {
+ GL.immediate.TexEnvJIT.traverseState(keyView);
}
- if (!cacheItem.renderer) {
+
+ // If we don't already have it, create it.
+ if (!keyView.get()) {
#if GL_DEBUG
Module.printErr('generating renderer for ' + JSON.stringify(attributes));
#endif
- cacheItem.renderer = this.createRenderer();
+ keyView.set(this.createRenderer());
}
- return cacheItem.renderer;
+ return keyView.get();
},
createRenderer: function(renderer) {
var useCurrProgram = !!GL.currProgram;
var hasTextures = false, textureSizes = [], textureTypes = [];
- for (var i = 0; i < GL.immediate.NUM_TEXTURES; i++) {
- if (GL.immediate.enabledClientAttributes[GL.immediate.TEXTURE0 + i]) {
- textureSizes[i] = GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + i].size;
- textureTypes[i] = GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + i].type;
- hasTextures = true;
+ for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) {
+ var texAttribName = GL.immediate.TEXTURE0 + i;
+ if (!GL.immediate.enabledClientAttributes[texAttribName])
+ continue;
+
+ if (!useCurrProgram) {
+ assert(GL.immediate.TexEnvJIT.getTexUnitType(i) != 0, "GL_TEXTURE" + i + " coords are supplied, but that texture unit is disabled in the fixed-function pipeline.");
}
+
+ textureSizes[i] = GL.immediate.clientAttributes[texAttribName].size;
+ textureTypes[i] = GL.immediate.clientAttributes[texAttribName].type;
+ hasTextures = true;
}
var positionSize = GL.immediate.clientAttributes[GL.immediate.VERTEX].size;
var positionType = GL.immediate.clientAttributes[GL.immediate.VERTEX].type;
@@ -2129,6 +3038,13 @@ var LibraryGL = {
}
var ret = {
init: function() {
+ // For fixed-function shader generation.
+ var uTexUnitPrefix = 'u_texUnit';
+ var aTexCoordPrefix = 'a_texCoord';
+ var vTexCoordPrefix = 'v_texCoord';
+ var vPrimColor = 'v_color';
+ var uTexMatrixPrefix = GL.immediate.useTextureMatrix ? 'u_textureMatrix' : null;
+
if (useCurrProgram) {
if (GL.shaderInfos[GL.programShaders[GL.currProgram][0]].type == Module.ctx.VERTEX_SHADER) {
this.vertexShader = GL.shaders[GL.programShaders[GL.currProgram][0]];
@@ -2138,13 +3054,12 @@ var LibraryGL = {
this.fragmentShader = GL.shaders[GL.programShaders[GL.currProgram][0]];
}
this.program = GL.programs[GL.currProgram];
+ this.usedTexUnitList = [];
} else {
// IMPORTANT NOTE: If you parameterize the shader source based on any runtime values
// in order to create the least expensive shader possible based on the features being
// used, you should also update the code in the beginning of getRenderer to make sure
// that you cache the renderer based on the said parameters.
- this.vertexShader = Module.ctx.createShader(Module.ctx.VERTEX_SHADER);
- var zero = positionSize == 2 ? '0, ' : '';
if (GLEmulation.fogEnabled) {
switch (GLEmulation.fogMode) {
case 0x0801: // GL_EXP2
@@ -2161,47 +3076,95 @@ var LibraryGL = {
break;
}
}
- Module.ctx.shaderSource(this.vertexShader, 'attribute vec' + positionSize + ' a_position; \n' +
- 'attribute vec2 a_texCoord0; \n' +
- (hasTextures ? 'varying vec2 v_texCoord; \n' : '') +
- 'varying vec4 v_color; \n' +
- (colorSize ? 'attribute vec4 a_color; \n': 'uniform vec4 u_color; \n') +
- (GLEmulation.fogEnabled ? 'varying float v_fogFragCoord; \n' : '') +
- 'uniform mat4 u_modelView; \n' +
- 'uniform mat4 u_projection; \n' +
- 'void main() \n' +
- '{ \n' +
- ' vec4 ecPosition = (u_modelView * vec4(a_position, ' + zero + '1.0)); \n' + // eye-coordinate position
- ' gl_Position = u_projection * ecPosition; \n' +
- (hasTextures ? 'v_texCoord = a_texCoord0; \n' : '') +
- (colorSize ? 'v_color = a_color; \n' : 'v_color = u_color; \n') +
- (GLEmulation.fogEnabled ? 'v_fogFragCoord = abs(ecPosition.z);\n' : '') +
- '} \n');
+
+ GL.immediate.TexEnvJIT.setGLSLVars(uTexUnitPrefix, vTexCoordPrefix, vPrimColor, uTexMatrixPrefix);
+ var fsTexEnvPass = GL.immediate.TexEnvJIT.genAllPassLines('gl_FragColor', 2);
+
+ var texUnitAttribList = '';
+ var texUnitVaryingList = '';
+ var texUnitUniformList = '';
+ var vsTexCoordInits = '';
+ this.usedTexUnitList = GL.immediate.TexEnvJIT.getUsedTexUnitList();
+ for (var i = 0; i < this.usedTexUnitList.length; i++) {
+ var texUnit = this.usedTexUnitList[i];
+ texUnitAttribList += 'attribute vec4 ' + aTexCoordPrefix + texUnit + ';\n';
+ texUnitVaryingList += 'varying vec4 ' + vTexCoordPrefix + texUnit + ';\n';
+ texUnitUniformList += 'uniform sampler2D ' + uTexUnitPrefix + texUnit + ';\n';
+ vsTexCoordInits += ' ' + vTexCoordPrefix + texUnit + ' = ' + aTexCoordPrefix + texUnit + ';\n';
+
+ if (GL.immediate.useTextureMatrix) {
+ texUnitUniformList += 'uniform mat4 ' + uTexMatrixPrefix + texUnit + ';\n';
+ }
+ }
+
+ var vsFogVaryingInit = null;
+ if (GLEmulation.fogEnabled) {
+ vsFogVaryingInit = ' v_fogFragCoord = abs(ecPosition.z);\n';
+ }
+
+ var vsSource = [
+ 'attribute vec4 a_position;',
+ 'attribute vec4 a_color;',
+ 'varying vec4 v_color;',
+ texUnitAttribList,
+ texUnitVaryingList,
+ (GLEmulation.fogEnabled ? 'varying float v_fogFragCoord;' : null),
+ 'uniform mat4 u_modelView;',
+ 'uniform mat4 u_projection;',
+ 'void main()',
+ '{',
+ ' vec4 ecPosition = u_modelView * a_position;', // eye-coordinate position
+ ' gl_Position = u_projection * ecPosition;',
+ ' v_color = a_color;',
+ vsTexCoordInits,
+ vsFogVaryingInit,
+ '}',
+ ''
+ ].join('\n').replace(/\n\n+/g, '\n');
+
+ this.vertexShader = Module.ctx.createShader(Module.ctx.VERTEX_SHADER);
+ Module.ctx.shaderSource(this.vertexShader, vsSource);
Module.ctx.compileShader(this.vertexShader);
+ var fogHeaderIfNeeded = null;
+ if (GLEmulation.fogEnabled) {
+ fogHeaderIfNeeded = [
+ '',
+ 'varying float v_fogFragCoord; ',
+ 'uniform vec4 u_fogColor; ',
+ 'uniform float u_fogEnd; ',
+ 'uniform float u_fogScale; ',
+ 'uniform float u_fogDensity; ',
+ 'float ffog(in float ecDistance) { ',
+ fogFormula,
+ ' fog = clamp(fog, 0.0, 1.0); ',
+ ' return fog; ',
+ '}',
+ '',
+ ].join("\n");
+ }
+
+ var fogPass = null;
+ if (GLEmulation.fogEnabled) {
+ fogPass = 'gl_FragColor = vec4(mix(u_fogColor.rgb, gl_FragColor.rgb, ffog(v_fogFragCoord)), gl_FragColor.a);\n';
+ }
+
+ var fsSource = [
+ 'precision mediump float;',
+ texUnitVaryingList,
+ texUnitUniformList,
+ 'varying vec4 v_color;',
+ fogHeaderIfNeeded,
+ 'void main()',
+ '{',
+ fsTexEnvPass,
+ fogPass,
+ '}',
+ ''
+ ].join("\n").replace(/\n\n+/g, '\n');
+
this.fragmentShader = Module.ctx.createShader(Module.ctx.FRAGMENT_SHADER);
- Module.ctx.shaderSource(this.fragmentShader, 'precision mediump float; \n' +
- 'varying vec2 v_texCoord; \n' +
- 'uniform sampler2D u_texture; \n' +
- 'varying vec4 v_color; \n' +
- (GLEmulation.fogEnabled ? (
- 'varying float v_fogFragCoord; \n' +
- 'uniform vec4 u_fogColor; \n' +
- 'uniform float u_fogEnd; \n' +
- 'uniform float u_fogScale; \n' +
- 'uniform float u_fogDensity; \n' +
- 'float ffog(in float ecDistance) { \n' +
- fogFormula +
- ' fog = clamp(fog, 0.0, 1.0); \n' +
- ' return fog; \n' +
- '} \n'
- ) : '') +
- 'void main() \n' +
- '{ \n' +
- (hasTextures ? 'gl_FragColor = v_color * texture2D( u_texture, v_texCoord );\n' :
- 'gl_FragColor = v_color;\n') +
- (GLEmulation.fogEnabled ? 'gl_FragColor = vec4(mix(u_fogColor.rgb, gl_FragColor.rgb, ffog(v_fogFragCoord)), gl_FragColor.a); \n' : '') +
- '} \n');
+ Module.ctx.shaderSource(this.fragmentShader, fsSource);
Module.ctx.compileShader(this.fragmentShader);
this.program = Module.ctx.createProgram();
@@ -2212,12 +3175,36 @@ var LibraryGL = {
}
this.positionLocation = Module.ctx.getAttribLocation(this.program, 'a_position');
+
this.texCoordLocations = [];
- for (var i = 0; i < textureSizes.length; i++) {
- if (textureSizes[i]) {
+
+ for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) {
+ if (!GL.immediate.enabledClientAttributes[GL.immediate.TEXTURE0 + i]) {
+ this.texCoordLocations[i] = -1;
+ continue;
+ }
+
+ if (useCurrProgram) {
this.texCoordLocations[i] = Module.ctx.getAttribLocation(this.program, 'a_texCoord' + i);
+ } else {
+ this.texCoordLocations[i] = Module.ctx.getAttribLocation(this.program, aTexCoordPrefix + i);
+ }
+ }
+
+ if (!useCurrProgram) {
+ // Temporarily switch to the program so we can set our sampler uniforms early.
+ var prevBoundProg = Module.ctx.getParameter(Module.ctx.CURRENT_PROGRAM);
+ Module.ctx.useProgram(this.program);
+ {
+ for (var i = 0; i < this.usedTexUnitList.length; i++) {
+ var texUnitID = this.usedTexUnitList[i];
+ var texSamplerLoc = Module.ctx.getUniformLocation(this.program, uTexUnitPrefix + texUnitID);
+ Module.ctx.uniform1i(texSamplerLoc, texUnitID);
+ }
}
+ Module.ctx.useProgram(prevBoundProg);
}
+
this.textureMatrixLocations = [];
for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) {
this.textureMatrixLocations[i] = Module.ctx.getUniformLocation(this.program, 'u_textureMatrix' + i);
@@ -2225,16 +3212,12 @@ var LibraryGL = {
this.colorLocation = Module.ctx.getAttribLocation(this.program, 'a_color');
this.normalLocation = Module.ctx.getAttribLocation(this.program, 'a_normal');
- this.textureLocation = Module.ctx.getUniformLocation(this.program, 'u_texture'); // only for immediate mode with no shaders, so only one is enough
this.modelViewLocation = Module.ctx.getUniformLocation(this.program, 'u_modelView');
this.projectionLocation = Module.ctx.getUniformLocation(this.program, 'u_projection');
- this.hasColorAttribLocation = Module.ctx.getUniformLocation(this.program, 'u_hasColorAttrib');
- this.colorUniformLocation = Module.ctx.getUniformLocation(this.program, 'u_color');
this.hasTextures = hasTextures;
- this.hasColorAttrib = colorSize > 0 && this.colorLocation >= 0;
- this.hasColorUniform = !!this.colorUniformLocation;
this.hasNormal = normalSize > 0 && this.normalLocation >= 0;
+ this.hasColor = (this.colorLocation === 0) || this.colorLocation > 0;
this.floatType = Module.ctx.FLOAT; // minor optimization
@@ -2294,6 +3277,7 @@ var LibraryGL = {
if (!GL.currProgram) {
Module.ctx.useProgram(this.program);
+ GL.immediate.fixedFunctionProgram = this.program;
}
if (this.modelViewLocation) Module.ctx.uniformMatrix4fv(this.modelViewLocation, false, GL.immediate.matrix['m']);
@@ -2305,11 +3289,21 @@ var LibraryGL = {
GL.immediate.stride, clientAttributes[GL.immediate.VERTEX].offset);
Module.ctx.enableVertexAttribArray(this.positionLocation);
if (this.hasTextures) {
- for (var i = 0; i < textureSizes.length; i++) {
- if (textureSizes[i] && this.texCoordLocations[i] >= 0) {
- Module.ctx.vertexAttribPointer(this.texCoordLocations[i], textureSizes[i], textureTypes[i], false,
- GL.immediate.stride, clientAttributes[GL.immediate.TEXTURE0 + i].offset);
- Module.ctx.enableVertexAttribArray(this.texCoordLocations[i]);
+ //for (var i = 0; i < this.usedTexUnitList.length; i++) {
+ // var texUnitID = this.usedTexUnitList[i];
+ for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) {
+ var texUnitID = i;
+ var attribLoc = this.texCoordLocations[texUnitID];
+ if (attribLoc === undefined || attribLoc < 0) continue;
+
+ if (texUnitID < textureSizes.length && textureSizes[texUnitID]) {
+ Module.ctx.vertexAttribPointer(attribLoc, textureSizes[texUnitID], textureTypes[texUnitID], false,
+ GL.immediate.stride, GL.immediate.clientAttributes[GL.immediate.TEXTURE0 + texUnitID].offset);
+ Module.ctx.enableVertexAttribArray(attribLoc);
+ } else {
+ // These two might be dangerous, but let's try them.
+ Module.ctx.vertexAttrib4f(attribLoc, 0, 0, 0, 1);
+ Module.ctx.disableVertexAttribArray(attribLoc);
}
}
for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) {
@@ -2318,26 +3312,19 @@ var LibraryGL = {
}
}
}
- if (this.hasColorAttrib) {
+ if (colorSize) {
Module.ctx.vertexAttribPointer(this.colorLocation, colorSize, colorType, true,
GL.immediate.stride, clientAttributes[GL.immediate.COLOR].offset);
Module.ctx.enableVertexAttribArray(this.colorLocation);
- Module.ctx.uniform1i(this.hasColorAttribLocation, 1);
- } else if (this.hasColorUniform) {
- Module.ctx.uniform1i(this.hasColorAttribLocation, 0);
- Module.ctx.uniform4fv(this.colorUniformLocation, GL.immediate.clientColor);
+ } else if (this.hasColor) {
+ Module.ctx.disableVertexAttribArray(this.colorLocation);
+ Module.ctx.vertexAttrib4fv(this.colorLocation, GL.immediate.clientColor);
}
if (this.hasNormal) {
Module.ctx.vertexAttribPointer(this.normalLocation, normalSize, normalType, true,
GL.immediate.stride, clientAttributes[GL.immediate.NORMAL].offset);
Module.ctx.enableVertexAttribArray(this.normalLocation);
}
- if (!useCurrProgram) { // otherwise, the user program will set the sampler2D binding and uniform itself
- var texture = Module.ctx.getParameter(Module.ctx.TEXTURE_BINDING_2D);
- Module.ctx.activeTexture(Module.ctx.TEXTURE0);
- Module.ctx.bindTexture(Module.ctx.TEXTURE_2D, texture);
- Module.ctx.uniform1i(this.textureLocation, 0);
- }
if (this.hasFog) {
if (this.fogColorLocation) Module.ctx.uniform4fv(this.fogColorLocation, GLEmulation.fogColor);
if (this.fogEndLocation) Module.ctx.uniform1f(this.fogEndLocation, GLEmulation.fogEnd);
@@ -2355,7 +3342,7 @@ var LibraryGL = {
}
}
}
- if (this.hasColorAttrib) {
+ if (this.hasColor) {
Module.ctx.disableVertexAttribArray(this.colorLocation);
}
if (this.hasNormal) {
@@ -2408,6 +3395,9 @@ var LibraryGL = {
if (!GL.currElementArrayBuffer) {
assert(type == Module.ctx.UNSIGNED_SHORT); // We can only emulate buffers of this kind, for now
}
+#if ASSERTIONS
+ console.log("DrawElements doesn't actually prepareClientAttributes properly.");
+#endif
GL.immediate.prepareClientAttributes(count, false);
GL.immediate.mode = mode;
if (!GL.currArrayBuffer) {
@@ -2418,6 +3408,76 @@ var LibraryGL = {
GL.immediate.flush(count, 0, indices);
GL.immediate.mode = -1;
};
+
+ // TexEnv stuff needs to be prepared early, so do it here.
+ // init() is too late for -O2, since it freezes the GL functions
+ // by that point.
+ GL.immediate.MapTreeLib = GL.immediate.spawnMapTreeLib();
+ GL.immediate.spawnMapTreeLib = null;
+
+ GL.immediate.TexEnvJIT = GL.immediate.spawnTexEnvJIT();
+ GL.immediate.spawnTexEnvJIT = null;
+
+ GL.immediate.setupHooks();
+ },
+
+ setupHooks: function() {
+ if (!GLEmulation.hasRunInit) {
+ GLEmulation.init();
+ }
+
+ var glActiveTexture = _glActiveTexture;
+ _glActiveTexture = function(texture) {
+ GL.immediate.TexEnvJIT.hook_activeTexture(texture);
+ glActiveTexture(texture);
+ };
+
+ var glEnable = _glEnable;
+ _glEnable = function(cap) {
+ GL.immediate.TexEnvJIT.hook_enable(cap);
+ glEnable(cap);
+ };
+ var glDisable = _glDisable;
+ _glDisable = function(cap) {
+ GL.immediate.TexEnvJIT.hook_disable(cap);
+ glDisable(cap);
+ };
+
+ var glTexEnvf = (typeof(_glTexEnvf) != 'undefined') ? _glTexEnvf : function(){};
+ _glTexEnvf = function(target, pname, param) {
+ GL.immediate.TexEnvJIT.hook_texEnvf(target, pname, param);
+ // Don't call old func, since we are the implementor.
+ //glTexEnvf(target, pname, param);
+ };
+ var glTexEnvi = (typeof(_glTexEnvi) != 'undefined') ? _glTexEnvi : function(){};
+ _glTexEnvi = function(target, pname, param) {
+ GL.immediate.TexEnvJIT.hook_texEnvi(target, pname, param);
+ // Don't call old func, since we are the implementor.
+ //glTexEnvi(target, pname, param);
+ };
+ var glTexEnvfv = (typeof(_glTexEnvfv) != 'undefined') ? _glTexEnvfv : function(){};
+ _glTexEnvfv = function(target, pname, param) {
+ GL.immediate.TexEnvJIT.hook_texEnvfv(target, pname, param);
+ // Don't call old func, since we are the implementor.
+ //glTexEnvfv(target, pname, param);
+ };
+
+ var glGetIntegerv = _glGetIntegerv;
+ _glGetIntegerv = function(pname, params) {
+ switch (pname) {
+ case 0x8B8D: { // GL_CURRENT_PROGRAM
+ // Just query directly so we're working with WebGL objects.
+ var cur = Module.ctx.getParameter(Module.ctx.CURRENT_PROGRAM);
+ if (cur == GL.immediate.fixedFunctionProgram) {
+ // Pretend we're not using a program.
+ {{{ makeSetValue('params', '0', '0', 'i32') }}};
+ return;
+ }
+ break;
+ }
+ }
+ glGetIntegerv(pname, params);
+ };
},
// Main functions
@@ -2428,6 +3488,15 @@ var LibraryGL = {
if (!Module.useWebGL) return; // a 2D canvas may be currently used TODO: make sure we are actually called in that case
+ this.TexEnvJIT.init(Module.ctx);
+
+ GL.immediate.MAX_TEXTURES = Module.ctx.getParameter(Module.ctx.MAX_TEXTURE_IMAGE_UNITS);
+ GL.immediate.NUM_ATTRIBUTES = GL.immediate.TEXTURE0 + GL.immediate.MAX_TEXTURES;
+ GL.immediate.clientAttributes = [];
+ for (var i = 0; i < GL.immediate.NUM_ATTRIBUTES; i++) {
+ GL.immediate.clientAttributes.push({});
+ }
+
this.matrixStack['m'] = [];
this.matrixStack['p'] = [];
for (var i = 0; i < GL.immediate.MAX_TEXTURES; i++) {
@@ -2445,7 +3514,7 @@ var LibraryGL = {
}
// Renderer cache
- this.rendererCache = this.rendererCacheItemTemplate.slice();
+ this.rendererCache = this.MapTreeLib.create();
// Buffers for data
this.tempData = new Float32Array(GL.MAX_TEMP_BUFFER_SIZE >> 2);
@@ -2486,6 +3555,7 @@ var LibraryGL = {
if (stride != 0 && stride != attribute.stride) multiStrides = true;
if (attribute.stride) stride = attribute.stride;
}
+
if (multiStrides) stride = 0; // we will need to restride
var bytes = 0; // total size in bytes
if (!stride && !beginEnd) {
@@ -2564,8 +3634,8 @@ var LibraryGL = {
var renderer = this.getRenderer();
// Generate index data in a format suitable for GLES 2.0/WebGL
- var numVertexes = 4 * this.vertexCounter / GL.immediate.stride; // XXX assuming float
- assert(numVertexes % 1 == 0);
+ var numVertexes = 4 * this.vertexCounter / GL.immediate.stride;
+ assert(numVertexes % 1 == 0, "`numVertexes` must be an integer.");
var emulatedElementArrayBuffer = false;
var numIndexes = 0;
@@ -2629,6 +3699,16 @@ var LibraryGL = {
glBegin__deps: ['$GLImmediateSetup'],
glBegin: function(mode) {
+ // Push the old state:
+ GL.immediate.enabledClientAttributes_preBegin = GL.immediate.enabledClientAttributes;
+ GL.immediate.enabledClientAttributes = [];
+
+ GL.immediate.clientAttributes_preBegin = GL.immediate.clientAttributes;
+ GL.immediate.clientAttributes = []
+ for (var i = 0; i < GL.immediate.clientAttributes_preBegin.length; i++) {
+ GL.immediate.clientAttributes.push({});
+ }
+
GL.immediate.mode = mode;
GL.immediate.vertexCounter = 0;
var components = GL.immediate.rendererComponents = [];
@@ -2646,6 +3726,12 @@ var LibraryGL = {
GL.immediate.flush();
GL.immediate.disableBeginEndClientAttributes();
GL.immediate.mode = -1;
+
+ // Pop the old state:
+ GL.immediate.enabledClientAttributes = GL.immediate.enabledClientAttributes_preBegin;
+ GL.immediate.clientAttributes = GL.immediate.clientAttributes_preBegin;
+
+ GL.immediate.modifiedClientAttributes = true;
},
glVertex3f: function(x, y, z) {
@@ -2670,7 +3756,7 @@ var LibraryGL = {
glVertex2fv: function(p) {
_glVertex3f({{{ makeGetValue('p', '0', 'float') }}}, {{{ makeGetValue('p', '4', 'float') }}}, 0);
},
-
+
glVertex3i: 'glVertex3f',
glVertex2i: 'glVertex3f',
@@ -2879,11 +3965,11 @@ var LibraryGL = {
},
// Vertex array object (VAO) support. TODO: when the WebGL extension is popular, use that and remove this code and GL.vaos
- glGenVertexArrays__deps: ['$GLEMulation'],
+ glGenVertexArrays__deps: ['$GLEmulation'],
glGenVertexArrays__sig: 'vii',
glGenVertexArrays: function(n, vaos) {
for (var i = 0; i < n; i++) {
- var id = GL.getNewId(GLEmulation.vaos);
+ var id = GL.getNewId(GLEmulation.vaos);
GLEmulation.vaos[id] = {
id: id,
arrayBuffer: 0,
@@ -2944,6 +4030,7 @@ var LibraryGL = {
} else if (mode == 0x1701 /* GL_PROJECTION */) {
GL.immediate.currentMatrix = 'p';
} else if (mode == 0x1702) { // GL_TEXTURE
+ GL.immediate.useTextureMatrix = true;
GL.immediate.currentMatrix = 't' + GL.immediate.clientActiveTexture;
} else {
throw "Wrong mode " + mode + " passed to glMatrixMode";
@@ -3113,7 +4200,7 @@ var LibraryGL = {
return 1 /* GL_TRUE */;
},
-
+
gluOrtho2D: function(left, right, bottom, top) {
_glOrtho(left, right, bottom, top, -1, 1);
},
@@ -3280,9 +4367,10 @@ var LibraryGL = {
glGenVertexArraysOES: 'glGenVertexArrays',
glDeleteVertexArraysOES: 'glDeleteVertexArrays',
glBindVertexArrayOES: 'glBindVertexArray',
- glFramebufferTexture2DOES: 'glFramebufferTexture2D'
+ glFramebufferTexture2DOES: 'glFramebufferTexture2D',
};
+
// Simple pass-through functions. Starred ones have return values. [X] ones have X in the C name but not in the JS name
[[0, 'getError* finish flush'],
[1, 'clearDepth clearDepth[f] depthFunc enable disable frontFace cullFace clear lineWidth clearStencil depthMask stencilMask checkFramebufferStatus* generateMipmap activeTexture blendEquation sampleCoverage isEnabled*'],
diff --git a/src/library_sdl.js b/src/library_sdl.js
index d31c37f5..4f871f9d 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -694,6 +694,11 @@ var LibrarySDL = {
Module['canvas'].addEventListener(event, SDL.receiveEvent, true);
});
Browser.setCanvasSize(width, height, true);
+ // Free the old surface first.
+ if (SDL.screen) {
+ SDL.freeSurface(SDL.screen);
+ SDL.screen = null;
+ }
SDL.screen = SDL.makeSurface(width, height, flags, true, 'screen');
if (!SDL.addedResizeListener) {
SDL.addedResizeListener = true;
diff --git a/src/parseTools.js b/src/parseTools.js
index 45046558..3949491e 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2038,12 +2038,20 @@ function processMathop(item) {
}
var bitsBefore = parseInt((item.params[0] ? item.params[0].type : item.type).substr(1)); // remove i to leave the number of bits left after this
var bitsLeft = parseInt(((item.params[1] && item.params[1].ident) ? item.params[1].ident : item.type).substr(1)); // remove i to leave the number of bits left after this operation
+ var rawBits = getBits(item.type);
+ assert(rawBits <= 64);
function integerizeBignum(value) {
return makeInlineCalculation('VALUE-VALUE%1', value, 'tempBigIntI');
}
- if ((type == 'i64' || paramTypes[0] == 'i64' || paramTypes[1] == 'i64' || idents[1] == '(i64)') && USE_TYPED_ARRAYS == 2) {
+ if ((type == 'i64' || paramTypes[0] == 'i64' || paramTypes[1] == 'i64' || idents[1] == '(i64)' || rawBits > 32) && USE_TYPED_ARRAYS == 2) {
+ // this code assumes i64 for the most part
+ if (ASSERTIONS && rawBits > 1 && rawBits < 64) {
+ warnOnce('processMathop processing illegal non-i64 value');
+ if (VERBOSE) printErr([op, item.type, rawBits, type, paramTypes, idents]);
+ }
+
var warnI64_1 = function() {
warnOnce('Arithmetic on 64-bit integers in mode 1 is rounded and flaky, like mode 0!');
};
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp
index 61daed79..8c72b0a6 100644
--- a/src/relooper/Relooper.cpp
+++ b/src/relooper/Relooper.cpp
@@ -104,9 +104,6 @@ Block::Block(const char *CodeInit) : Parent(NULL), Id(Block::IdCounter++), Defau
Block::~Block() {
if (Code) free((void*)Code);
- for (BlockBranchMap::iterator iter = ProcessedBranchesIn.begin(); iter != ProcessedBranchesIn.end(); iter++) {
- delete iter->second;
- }
for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin(); iter != ProcessedBranchesOut.end(); iter++) {
delete iter->second;
}
@@ -139,10 +136,6 @@ void Block::Render(bool InLoop) {
bool SetLabel = true; // in some cases it is clear we can avoid setting label, see later
- if (ProcessedBranchesOut.size() == 1 && ProcessedBranchesOut.begin()->second->Type == Branch::Direct) {
- SetLabel = false;
- }
-
// A setting of the label variable (label = x) is necessary if it can
// cause an impact. The main case is where we set label to x, then elsewhere
// we check if label is equal to that value, i.e., that label is an entry
@@ -379,22 +372,47 @@ void Relooper::Calculate(Block *Entry) {
Block *Curr = *iter;
TotalCodeSize += strlen(Curr->Code);
}
-
+ BlockSet Splits;
+ BlockSet Removed;
+ //DebugDump(Live, "before");
for (BlockSet::iterator iter = Live.begin(); iter != Live.end(); iter++) {
Block *Original = *iter;
- if (Original->BranchesIn.size() <= 1 || Original->BranchesOut.size() > 0) continue;
+ if (Original->BranchesIn.size() <= 1 || Original->BranchesOut.size() > 0) continue; // only dead ends, for now
+ if (Original->BranchesOut.find(Original) != Original->BranchesOut.end()) continue; // cannot split a looping node
if (strlen(Original->Code)*(Original->BranchesIn.size()-1) > TotalCodeSize/5) continue; // if splitting increases raw code size by a significant amount, abort
// Split the node (for simplicity, we replace all the blocks, even though we could have reused the original)
- for (BlockBranchMap::iterator iter = Original->BranchesIn.begin(); iter != Original->BranchesIn.end(); iter++) {
- Block *Prior = iter->first;
+ PrintDebug("Splitting block %d\n", Original->Id);
+ for (BlockSet::iterator iter = Original->BranchesIn.begin(); iter != Original->BranchesIn.end(); iter++) {
+ Block *Prior = *iter;
Block *Split = new Block(Original->Code);
- Split->BranchesIn[Prior] = new Branch(NULL);
- Prior->BranchesOut[Split] = new Branch(Prior->BranchesOut[Original]->Condition, Prior->BranchesOut[Original]->Code);
+ Parent->Blocks.push_back(Split);
+ PrintDebug(" to %d\n", Split->Id);
+ Split->BranchesIn.insert(Prior);
+ Branch *Details = Prior->BranchesOut[Original];
+ Prior->BranchesOut[Split] = new Branch(Details->Condition, Details->Code);
Prior->BranchesOut.erase(Original);
- Parent->AddBlock(Split);
- Live.insert(Split);
+ for (BlockBranchMap::iterator iter = Original->BranchesOut.begin(); iter != Original->BranchesOut.end(); iter++) {
+ Block *Post = iter->first;
+ Branch *Details = iter->second;
+ Split->BranchesOut[Post] = new Branch(Details->Condition, Details->Code);
+ Post->BranchesIn.insert(Split);
+ }
+ Splits.insert(Split);
+ Removed.insert(Original);
+ }
+ for (BlockBranchMap::iterator iter = Original->BranchesOut.begin(); iter != Original->BranchesOut.end(); iter++) {
+ Block *Post = iter->first;
+ Post->BranchesIn.erase(Original);
}
+ //DebugDump(Live, "mid");
+ }
+ for (BlockSet::iterator iter = Splits.begin(); iter != Splits.end(); iter++) {
+ Live.insert(*iter);
+ }
+ for (BlockSet::iterator iter = Removed.begin(); iter != Removed.end(); iter++) {
+ Live.erase(*iter);
}
+ //DebugDump(Live, "after");
}
};
PreOptimizer Pre(this);
@@ -405,7 +423,7 @@ void Relooper::Calculate(Block *Entry) {
Block *Curr = Blocks[i];
if (Pre.Live.find(Curr) == Pre.Live.end()) continue;
for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
- iter->first->BranchesIn[Curr] = new Branch(NULL);
+ iter->first->BranchesIn.insert(Curr);
}
}
@@ -435,22 +453,21 @@ void Relooper::Calculate(Block *Entry) {
void Solipsize(Block *Target, Branch::FlowType Type, Shape *Ancestor, BlockSet &From) {
PrintDebug("Solipsizing branches into %d\n", Target->Id);
DebugDump(From, " relevant to solipsize: ");
- for (BlockBranchMap::iterator iter = Target->BranchesIn.begin(); iter != Target->BranchesIn.end();) {
- Block *Prior = iter->first;
+ for (BlockSet::iterator iter = Target->BranchesIn.begin(); iter != Target->BranchesIn.end();) {
+ Block *Prior = *iter;
if (From.find(Prior) == From.end()) {
iter++;
continue;
}
- Branch *TargetIn = iter->second;
Branch *PriorOut = Prior->BranchesOut[Target];
- PriorOut->Ancestor = Ancestor; // Do we need this info
- PriorOut->Type = Type; // on TargetIn too?
+ PriorOut->Ancestor = Ancestor;
+ PriorOut->Type = Type;
if (MultipleShape *Multiple = Shape::IsMultiple(Ancestor)) {
Multiple->NeedLoop++; // We are breaking out of this Multiple, so need a loop
}
iter++; // carefully increment iter before erasing
Target->BranchesIn.erase(Prior);
- Target->ProcessedBranchesIn[Prior] = TargetIn;
+ Target->ProcessedBranchesIn.insert(Prior);
Prior->BranchesOut.erase(Target);
Prior->ProcessedBranchesOut[Target] = PriorOut;
PrintDebug(" eliminated branch from %d\n", Prior->Id);
@@ -488,8 +505,8 @@ void Relooper::Calculate(Block *Entry) {
InnerBlocks.insert(Curr);
Blocks.erase(Curr);
// Add the elements prior to it
- for (BlockBranchMap::iterator iter = Curr->BranchesIn.begin(); iter != Curr->BranchesIn.end(); iter++) {
- Queue.insert(iter->first);
+ for (BlockSet::iterator iter = Curr->BranchesIn.begin(); iter != Curr->BranchesIn.end(); iter++) {
+ Queue.insert(*iter);
}
}
}
@@ -620,8 +637,8 @@ void Relooper::Calculate(Block *Entry) {
BlockList ToInvalidate;
for (BlockSet::iterator iter = CurrGroup.begin(); iter != CurrGroup.end(); iter++) {
Block *Child = *iter;
- for (BlockBranchMap::iterator iter = Child->BranchesIn.begin(); iter != Child->BranchesIn.end(); iter++) {
- Block *Parent = iter->first;
+ for (BlockSet::iterator iter = Child->BranchesIn.begin(); iter != Child->BranchesIn.end(); iter++) {
+ Block *Parent = *iter;
if (Helper.Ownership[Parent] != Helper.Ownership[Child]) {
ToInvalidate.push_back(Child);
}
@@ -751,8 +768,8 @@ void Relooper::Calculate(Block *Entry) {
Block *Entry = iter->first;
BlockSet &Group = iter->second;
BlockBlockSetMap::iterator curr = iter++; // iterate carefully, we may delete
- for (BlockBranchMap::iterator iterBranch = Entry->BranchesIn.begin(); iterBranch != Entry->BranchesIn.end(); iterBranch++) {
- Block *Origin = iterBranch->first;
+ for (BlockSet::iterator iterBranch = Entry->BranchesIn.begin(); iterBranch != Entry->BranchesIn.end(); iterBranch++) {
+ Block *Origin = *iterBranch;
if (Group.find(Origin) == Group.end()) {
// Reached from outside the group, so we cannot handle this
PrintDebug("Cannot handle group with entry %d because of incoming branch from %d\n", Entry->Id, Origin->Id);
@@ -821,13 +838,11 @@ void Relooper::Calculate(Block *Entry) {
// Main
BlockSet AllBlocks;
- for (int i = 0; i < Blocks.size(); i++) {
- AllBlocks.insert(Blocks[i]);
+ for (BlockSet::iterator iter = Pre.Live.begin(); iter != Pre.Live.end(); iter++) {
+ Block *Curr = *iter;
+ AllBlocks.insert(Curr);
#if DEBUG
- PrintDebug("Adding block %d (%s)\n", Blocks[i]->Id, Blocks[i]->Code);
- for (BlockBranchMap::iterator iter = Blocks[i]->BranchesOut.begin(); iter != Blocks[i]->BranchesOut.end(); iter++) {
- PrintDebug(" with branch out to %d\n", iter->first->Id);
- }
+ PrintDebug("Adding block %d (%s)\n", Curr->Id, Curr->Code);
#endif
}
@@ -874,10 +889,26 @@ void Relooper::Calculate(Block *Entry) {
func(Loop->Next); \
}
+ // Find the blocks that natural control flow can get us directly to, or through a multiple that we ignore
+ void FollowNaturalFlow(Shape *S, BlockSet &Out) {
+ SHAPE_SWITCH(S, {
+ Out.insert(Simple->Inner);
+ }, {
+ for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) {
+ FollowNaturalFlow(iter->second, Out);
+ }
+ FollowNaturalFlow(Multiple->Next, Out);
+ }, {
+ FollowNaturalFlow(Loop->Inner, Out);
+ });
+ }
+
// Remove unneeded breaks and continues.
// A flow operation is trivially unneeded if the shape we naturally get to by normal code
// execution is the same as the flow forces us to.
void RemoveUnneededFlows(Shape *Root, Shape *Natural=NULL) {
+ BlockSet NaturalBlocks;
+ FollowNaturalFlow(Natural, NaturalBlocks);
Shape *Next = Root;
while (Next) {
Root = Next;
@@ -892,7 +923,7 @@ void Relooper::Calculate(Block *Entry) {
for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) {
Block *Target = iter->first;
Branch *Details = iter->second;
- if (Details->Type != Branch::Direct && Target->Parent == Natural) {
+ if (Details->Type != Branch::Direct && NaturalBlocks.find(Target) != NaturalBlocks.end()) { // note: cannot handle split blocks
Details->Type = Branch::Direct;
if (MultipleShape *Multiple = Shape::IsMultiple(Details->Ancestor)) {
Multiple->NeedLoop--;
@@ -1007,12 +1038,32 @@ void Relooper::SetAsmJSMode(int On) {
#if DEBUG
// Debugging
-void DebugDump(BlockSet &Blocks, const char *prefix) {
+void Debugging::Dump(BlockSet &Blocks, const char *prefix) {
if (prefix) printf("%s ", prefix);
for (BlockSet::iterator iter = Blocks.begin(); iter != Blocks.end(); iter++) {
- printf("%d ", (*iter)->Id);
+ Block *Curr = *iter;
+ printf("%d:\n", Curr->Id);
+ for (BlockBranchMap::iterator iter2 = Curr->BranchesOut.begin(); iter2 != Curr->BranchesOut.end(); iter2++) {
+ Block *Other = iter2->first;
+ printf(" -> %d\n", Other->Id);
+ assert(Other->BranchesIn.find(Curr) != Other->BranchesIn.end());
+ }
}
- printf("\n");
+}
+
+void Debugging::Dump(Shape *S, const char *prefix) {
+ if (prefix) printf("%s ", prefix);
+ printf(" %d ", S->Id);
+ SHAPE_SWITCH(S, {
+ printf("<< Simple with block %d\n", Simple->Inner->Id);
+ }, {
+ printf("<< Multiple\n");
+ for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) {
+ printf(" with entry %d\n", iter->first->Id);
+ }
+ }, {
+ printf("<< Loop\n");
+ });
}
static void PrintDebug(const char *Format, ...) {
diff --git a/src/relooper/Relooper.h b/src/relooper/Relooper.h
index eac03738..34b6db08 100644
--- a/src/relooper/Relooper.h
+++ b/src/relooper/Relooper.h
@@ -41,6 +41,7 @@ struct Branch {
void Render(Block *Target, bool SetLabel);
};
+typedef std::set<Block*> BlockSet;
typedef std::map<Block*, Branch*> BlockBranchMap;
// Represents a basic block of code - some instructions that end with a
@@ -52,9 +53,9 @@ struct Block {
// processed branches.
// Blocks own the Branch objects they use, and destroy them when done.
BlockBranchMap BranchesOut;
- BlockBranchMap BranchesIn; // TODO: make this just a list of Incoming, without branch info - should be just on BranchesOut
+ BlockSet BranchesIn;
BlockBranchMap ProcessedBranchesOut;
- BlockBranchMap ProcessedBranchesIn;
+ BlockSet ProcessedBranchesIn;
Shape *Parent; // The shape we are directly inside
int Id; // A unique identifier
const char *Code; // The string representation of the code in this block. Owning pointer (we copy the input)
@@ -205,12 +206,12 @@ struct Relooper {
static void SetAsmJSMode(int On);
};
-typedef std::set<Block*> BlockSet;
typedef std::map<Block*, BlockSet> BlockBlockSetMap;
#if DEBUG
struct Debugging {
static void Dump(BlockSet &Blocks, const char *prefix=NULL);
+ static void Dump(Shape *S, const char *prefix=NULL);
};
#endif
diff --git a/src/relooper/fuzzer.py b/src/relooper/fuzzer.py
index 96929028..5f6bae3d 100644
--- a/src/relooper/fuzzer.py
+++ b/src/relooper/fuzzer.py
@@ -98,14 +98,14 @@ int main() {
open('fuzz.slow.js', 'w').write(slow)
open('fuzz.cpp', 'w').write(fast)
print '_'
- slow_out = subprocess.Popen(['/home/alon/Dev/odinmonkey/js/src/fast/js', '-m', '-n', 'fuzz.slow.js'], stdout=subprocess.PIPE).communicate()[0]
+ slow_out = subprocess.Popen(['mozjs', '-m', '-n', 'fuzz.slow.js'], stdout=subprocess.PIPE).communicate()[0]
print '.'
subprocess.call(['g++', 'fuzz.cpp', 'Relooper.o', '-o', 'fuzz', '-g'])
print '*'
subprocess.call(['./fuzz'], stdout=open('fuzz.fast.js', 'w'))
print '-'
- fast_out = subprocess.Popen(['/home/alon/Dev/odinmonkey/js/src/fast/js', '-m', '-n', 'fuzz.fast.js'], stdout=subprocess.PIPE).communicate()[0]
+ fast_out = subprocess.Popen(['mozjs', '-m', '-n', 'fuzz.fast.js'], stdout=subprocess.PIPE).communicate()[0]
print
if slow_out != fast_out:
diff --git a/src/relooper/test.cpp b/src/relooper/test.cpp
index 4275941b..7da990b5 100644
--- a/src/relooper/test.cpp
+++ b/src/relooper/test.cpp
@@ -190,5 +190,46 @@ int main() {
puts(buffer);
}
+
+ if (1) {
+ Relooper::SetOutputBuffer(buffer, sizeof(buffer));
+
+ printf("\n\n-- if (expensive || expensive2) X else Y; Z --\n\n");
+
+ Block *b_a = new Block("// block A\n");
+ Block *b_b = new Block("// block B\n");
+ Block *b_c = new Block("// block C;\n");
+ Block *b_d = new Block("// block D\n");
+ Block *b_e = new Block("// block E\n");
+ Block *b_f = new Block("// block F\n");
+
+ b_a->AddBranchTo(b_c, "expensive()");
+ b_a->AddBranchTo(b_b, NULL);
+
+ b_b->AddBranchTo(b_c, "expensive2()");
+ b_b->AddBranchTo(b_d, NULL);
+
+ b_c->AddBranchTo(b_e, NULL);
+
+ b_d->AddBranchTo(b_e, NULL);
+
+ b_e->AddBranchTo(b_f, NULL);
+
+ b_f->AddBranchTo(b_e, NULL);
+
+ Relooper r;
+ r.AddBlock(b_a);
+ r.AddBlock(b_b);
+ r.AddBlock(b_c);
+ r.AddBlock(b_d);
+ r.AddBlock(b_e);
+ r.AddBlock(b_f);
+
+ r.Calculate(b_a);
+ printf("\n\n");
+ r.Render();
+
+ puts(buffer);
+ }
}
diff --git a/src/relooper/test.txt b/src/relooper/test.txt
index 12d0ef39..d657c6af 100644
--- a/src/relooper/test.txt
+++ b/src/relooper/test.txt
@@ -109,3 +109,30 @@ while(1) {
// block D
}
+
+
+-- if (expensive || expensive2) X else Y; Z --
+
+
+
+// block A
+do {
+ if (expensive()) {
+ label = 33;
+ } else {
+ // block B
+ if (expensive2()) {
+ label = 33;
+ break;
+ }
+ // block D
+ }
+} while(0);
+if (label == 33) {
+ // block C;
+}
+while(1) {
+ // block E
+ // block F
+}
+
diff --git a/src/relooper/test4.txt b/src/relooper/test4.txt
index f0bfb972..3427ff18 100644
--- a/src/relooper/test4.txt
+++ b/src/relooper/test4.txt
@@ -7,7 +7,6 @@ do {
break;
}
//21
- break;
} else {
label = 4;
}
diff --git a/src/relooper/test_debug.txt b/src/relooper/test_debug.txt
index 1c7d0508..d18ed875 100644
--- a/src/relooper/test_debug.txt
+++ b/src/relooper/test_debug.txt
@@ -28,56 +28,88 @@ int main() {
return 0;
}
// Adding block 1 (ep)
-// with branch out to 2
-// with branch out to 4
// Adding block 2 (LBB1)
-// with branch out to 3
-// with branch out to 4
// Adding block 3 (LBB2)
-// with branch out to 4
// Adding block 4 (LBB3)
// Process() called
// Process() running
- blocks : 1 2 3 4
- entries: 1
+ blocks : 1:
+ -> 2
+ -> 4
+2:
+ -> 3
+ -> 4
+3:
+ -> 4
+4:
+ entries: 1:
+ -> 2
+ -> 4
// creating simple block with block #1
// Solipsizing branches into 2
- relevant to solipsize: 1
+ relevant to solipsize: 1:
+ -> 2
+ -> 4
// eliminated branch from 1
// Solipsizing branches into 4
- relevant to solipsize: 1
+ relevant to solipsize: 1:
+ -> 4
// eliminated branch from 1
// Process() running
- blocks : 2 3 4
- entries: 2 4
+ blocks : 2:
+ -> 3
+ -> 4
+3:
+ -> 4
+4:
+ entries: 2:
+ -> 3
+ -> 4
+4:
// Investigated independent groups:
- group: 2 3
+ group: 2:
+ -> 3
+ -> 4
+3:
+ -> 4
// Independent groups: 1
// Handleable independent groups: 1
// creating multiple block with 1 inner groups
// multiple group with entry 2:
- 2 3
+ 2:
+ -> 3
+ -> 4
+3:
+ -> 4
// Solipsizing branches into 4
- relevant to solipsize: 2 3
+ relevant to solipsize: 2:
+ -> 3
+ -> 4
+3:
+ -> 4
// eliminated branch from 2
// eliminated branch from 3
// Process() called
// Process() running
- blocks : 2 3
- entries: 2
+ blocks : 2:
+ -> 3
+3:
+ entries: 2:
+ -> 3
// creating simple block with block #2
// Solipsizing branches into 3
- relevant to solipsize: 2
+ relevant to solipsize: 2:
+ -> 3
// eliminated branch from 2
// Process() running
- blocks : 3
- entries: 3
+ blocks : 3:
+ entries: 3:
// creating simple block with block #3
// Process() returning
- remaining blocks after multiple: 4
+ remaining blocks after multiple: 4:
// Process() running
- blocks : 4
- entries: 4
+ blocks : 4:
+ entries: 4:
// creating simple block with block #4
// Process() returning
// === Optimizing shapes ===
diff --git a/src/relooper/test_fuzz1.txt b/src/relooper/test_fuzz1.txt
index 5122257e..b278e240 100644
--- a/src/relooper/test_fuzz1.txt
+++ b/src/relooper/test_fuzz1.txt
@@ -3,13 +3,10 @@
print('entry'); var label; var state; var decisions = [4, 1, 7, 2, 6, 6, 8]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }
print(5); state = check();
print(6); state = check();
-do {
- if (state == 7) {
- print(7); state = check();
- label = 3;
- break;
- }
-} while(0);
+if (state == 7) {
+ print(7); state = check();
+ label = 3;
+}
L5: while(1) {
if (label == 3) {
label = 0;
diff --git a/src/relooper/test_fuzz5.txt b/src/relooper/test_fuzz5.txt
index 9548205c..29b2dba4 100644
--- a/src/relooper/test_fuzz5.txt
+++ b/src/relooper/test_fuzz5.txt
@@ -3,22 +3,18 @@
print('entry'); var label; var state; var decisions = [133, 98, 134, 143, 162, 187, 130, 87, 91, 49, 102, 47, 9, 132, 179, 176, 157, 25, 64, 161, 57, 107, 16, 167, 185, 45, 191, 180, 23, 131]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }
L1: while(1) {
print(7); state = check();
- do {
- if (state % 3 == 1) {
- label = 3;
- } else if (state % 3 == 0) {
- print(8); state = check();
- if (state % 2 == 0) {
- label = 5;
- break;
- } else {
- label = 7;
- break;
- }
+ if (state % 3 == 1) {
+ label = 3;
+ } else if (state % 3 == 0) {
+ print(8); state = check();
+ if (state % 2 == 0) {
+ label = 5;
} else {
- break L1;
+ label = 7;
}
- } while(0);
+ } else {
+ break;
+ }
while(1) {
if (label == 3) {
label = 0;
diff --git a/src/relooper/test_fuzz6.txt b/src/relooper/test_fuzz6.txt
index bd45e8fd..d5a5ab7b 100644
--- a/src/relooper/test_fuzz6.txt
+++ b/src/relooper/test_fuzz6.txt
@@ -82,7 +82,6 @@ while(1) {
print(56); state = check();// ....................................................................................................................................................................................................................
print(34); state = check();// ..........................................................................................................................................
label = 74;
- continue;
}
print(62); state = check();// .......................................................................................
}
diff --git a/src/relooper/testit.sh b/src/relooper/testit.sh
index 61e1a2fb..88db35fb 100755
--- a/src/relooper/testit.sh
+++ b/src/relooper/testit.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
echo "test"
./test &> test.out
diff --git a/src/relooper/updateit.sh b/src/relooper/updateit.sh
index 8c434753..da9fa9aa 100755
--- a/src/relooper/updateit.sh
+++ b/src/relooper/updateit.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
./test &> test.txt
./test2 &> test2.txt
./test3 &> test3.txt
diff --git a/system/include/libcxx/exception b/system/include/libcxx/exception
index 4b5770b7..102b10d6 100644
--- a/system/include/libcxx/exception
+++ b/system/include/libcxx/exception
@@ -91,8 +91,8 @@ class _LIBCPP_EXCEPTION_ABI exception
{
public:
_LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
- virtual ~exception() _NOEXCEPT {}; // XXX EMSCRIPTEN inline in destructor
- virtual const char* what() const _NOEXCEPT;
+ virtual ~exception() _NOEXCEPT {} // XXX EMSCRIPTEN - implement in header
+ virtual const char* what() const _NOEXCEPT { return "std::exception"; } // XXX EMSCRIPTEN - implement in header
};
class _LIBCPP_EXCEPTION_ABI bad_exception
diff --git a/tests/aniso.c b/tests/aniso.c
index e02c20ac..1126265e 100644
--- a/tests/aniso.c
+++ b/tests/aniso.c
@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
const char *exts = (const char *)glGetString(GL_EXTENSIONS);
assert(hasext(exts, "GL_EXT_texture_filter_anisotropic"));
-
+
GLint aniso;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &aniso);
printf("Max anisotropy: %d (using that)\n", aniso);
@@ -73,10 +73,8 @@ int main(int argc, char *argv[])
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 600, 600 );
@@ -155,7 +153,7 @@ int main(int argc, char *argv[])
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
int w = 10;
int n = 15;
@@ -200,7 +198,7 @@ int main(int argc, char *argv[])
}
*/
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(2000);
@@ -208,8 +206,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/cases/fp80.ll b/tests/cases/fp80_ta2.ll
index 7fc0db4a..7fc0db4a 100644
--- a/tests/cases/fp80.ll
+++ b/tests/cases/fp80_ta2.ll
diff --git a/tests/cases/muli33_ta2.ll b/tests/cases/muli33_ta2.ll
new file mode 100644
index 00000000..b33b04f7
--- /dev/null
+++ b/tests/cases/muli33_ta2.ll
@@ -0,0 +1,114 @@
+; ModuleID = '/tmp/tmpt0JpDh/a.out.bc'
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
+
+@.str = private unnamed_addr constant [7 x i8] c"20\0A91\0A\00", align 1
+@.str1 = private unnamed_addr constant [6 x i8] c"%u %u\00", align 1
+@.str2 = private unnamed_addr constant [10 x i8] c"res = %u\0A\00", align 1
+
+define i32 @main() nounwind {
+ %j = alloca i32, align 4
+ %k4 = alloca i32, align 4
+ %t = alloca [100 x [100 x i32]], align 4
+ store i32 20, i32* %j, align 4
+ store i32 91, i32* %k4, align 4
+ br label %.lr.ph.i
+
+.lr.ph.i: ; preds = %.lr.ph.i, %0
+ %j.07.i = phi i32 [ %7, %.lr.ph.i ], [ 0, %0 ]
+ %1 = and i32 %j.07.i, 1
+ %2 = icmp eq i32 %1, 0
+ %3 = sub i32 0, %j.07.i
+ %.p.i = select i1 %2, i32 %j.07.i, i32 %3
+ %4 = add i32 %.p.i, 8
+ %5 = urem i32 %4, 101
+ %6 = getelementptr inbounds [100 x [100 x i32]]* %t, i32 0, i32 0, i32 %j.07.i
+ store i32 %5, i32* %6, align 4
+ %7 = add i32 %j.07.i, 1
+ %8 = icmp ult i32 %7, 10000
+ br i1 %8, label %.lr.ph.i, label %init.exit
+
+init.exit: ; preds = %.lr.ph.i
+ %9 = call i32 (i8*, i8*, ...)* @sscanf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0), i32* %j, i32* %k4) nounwind
+ store i32 53, i32* %j, align 4
+ br label %.preheader
+
+.preheader: ; preds = %29, %init.exit
+ %indvars.iv23 = phi i32 [ -29, %init.exit ], [ %indvars.iv.next24, %29 ]
+ %indvars.iv21 = phi i32 [ -28, %init.exit ], [ %indvars.iv.next22, %29 ]
+ %indvars.iv19 = phi i32 [ -27, %init.exit ], [ %indvars.iv.next20, %29 ]
+ %indvars.iv17 = phi i32 [ 109, %init.exit ], [ %indvars.iv.next18, %29 ]
+ %indvars.iv15 = phi i32 [ -75923, %init.exit ], [ %indvars.iv.next16, %29 ]
+ %indvars.iv13 = phi i32 [ 5593, %init.exit ], [ %indvars.iv.next14, %29 ]
+ %indvars.iv = phi i32 [ -262, %init.exit ], [ %indvars.iv.next, %29 ]
+ %10 = phi i32 [ 53, %init.exit ], [ %.pre-phi, %29 ]
+ %11 = zext i32 %indvars.iv19 to i33
+ %12 = zext i32 %indvars.iv21 to i33
+ %13 = mul i33 %11, %12
+ %14 = icmp ult i32 %10, 27
+ br i1 %14, label %.lr.ph, label %.preheader._crit_edge
+
+.preheader._crit_edge: ; preds = %.preheader
+ %.pre = add i32 %10, -1
+ br label %29
+
+.lr.ph: ; preds = %.preheader
+ %15 = zext i32 %indvars.iv23 to i33
+ %16 = mul i33 %13, %15
+ %17 = lshr i33 %16, 1
+ %18 = lshr i33 %13, 1
+ %19 = trunc i33 %17 to i32
+ %20 = trunc i33 %18 to i32
+ %21 = mul i32 %19, 1431655766
+ %22 = mul i32 %indvars.iv17, %20
+ %23 = add i32 %10, -1
+ %24 = add i32 %10, 1
+ %25 = getelementptr inbounds [100 x [100 x i32]]* %t, i32 0, i32 %24, i32 %23
+ %.promoted = load i32* %25, align 4
+ %26 = add i32 %.promoted, %indvars.iv15
+ %27 = add i32 %26, %22
+ %28 = add i32 %27, %21
+ store i32 %28, i32* %25, align 4
+ br label %29
+
+.lr.ph.i3.preheader: ; preds = %29
+ store i32 2, i32* %j, align 4
+ store i32 %.lcssa69, i32* %k4, align 4
+ br label %.lr.ph.i3
+
+; <label>:29 ; preds = %.lr.ph, %.preheader._crit_edge
+ %.pre-phi = phi i32 [ %.pre, %.preheader._crit_edge ], [ %23, %.lr.ph ]
+ %.lcssa69 = phi i32 [ %10, %.preheader._crit_edge ], [ 27, %.lr.ph ]
+ %30 = icmp ugt i32 %.pre-phi, 2
+ %indvars.iv.next = add i32 %indvars.iv, 6
+ %indvars.iv.next14 = add i32 %indvars.iv13, %indvars.iv
+ %indvars.iv.next16 = add i32 %indvars.iv15, %indvars.iv13
+ %indvars.iv.next18 = add i32 %indvars.iv17, -2
+ %indvars.iv.next20 = add i32 %indvars.iv19, 1
+ %indvars.iv.next22 = add i32 %indvars.iv21, 1
+ %indvars.iv.next24 = add i32 %indvars.iv23, 1
+ br i1 %30, label %.preheader, label %.lr.ph.i3.preheader
+
+.lr.ph.i3: ; preds = %.lr.ph.i3, %.lr.ph.i3.preheader
+ %sum.07.i = phi i32 [ %37, %.lr.ph.i3 ], [ 0, %.lr.ph.i3.preheader ]
+ %j.06.i = phi i32 [ %38, %.lr.ph.i3 ], [ 0, %.lr.ph.i3.preheader ]
+ %31 = and i32 %j.06.i, 1
+ %32 = icmp eq i32 %31, 0
+ %33 = getelementptr inbounds [100 x [100 x i32]]* %t, i32 0, i32 0, i32 %j.06.i
+ %34 = load i32* %33, align 4
+ %35 = sub i32 0, %34
+ %36 = select i1 %32, i32 %34, i32 %35
+ %37 = add i32 %36, %sum.07.i
+ %38 = add i32 %j.06.i, 1
+ %39 = icmp ult i32 %38, 10000
+ br i1 %39, label %.lr.ph.i3, label %checkSum.exit
+
+checkSum.exit: ; preds = %.lr.ph.i3
+ %40 = add i32 %37, 2
+ %41 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str2, i32 0, i32 0), i32 %40) nounwind
+ ret i32 0
+}
+
+declare i32 @sscanf(i8* nocapture, i8* nocapture, ...) nounwind
+
+declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/tests/cases/muli33_ta2.txt b/tests/cases/muli33_ta2.txt
new file mode 100644
index 00000000..21e0231f
--- /dev/null
+++ b/tests/cases/muli33_ta2.txt
@@ -0,0 +1 @@
+res = 3164
diff --git a/tests/cases/philoop.ll b/tests/cases/philoop_ta2.ll
index 5036c7ba..5036c7ba 100644
--- a/tests/cases/philoop.ll
+++ b/tests/cases/philoop_ta2.ll
diff --git a/tests/cases/philoop.txt b/tests/cases/philoop_ta2.txt
index d5117fe8..d5117fe8 100644
--- a/tests/cases/philoop.txt
+++ b/tests/cases/philoop_ta2.txt
diff --git a/tests/files.cpp b/tests/files.cpp
index 04baa151..176cdb62 100644
--- a/tests/files.cpp
+++ b/tests/files.cpp
@@ -56,6 +56,9 @@ int main()
fwrite(data, 1, 5, outf);
fclose(outf);
+ FILE *devNull = fopen("/dev/null", "rb");
+ assert(devNull);
+
char data2[10];
FILE *inf = fopen("go.out", "rb");
int num = fread(data2, 1, 10, inf);
diff --git a/tests/full_es2_sdlproc.c b/tests/full_es2_sdlproc.c
new file mode 100644
index 00000000..d9ac072b
--- /dev/null
+++ b/tests/full_es2_sdlproc.c
@@ -0,0 +1,727 @@
+/*
+ * 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++)
+ glDrawElements(GL_TRIANGLE_STRIP, gear->strips[n].count, GL_FLOAT, gear->strips[n].first);
+
+ /* 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[])
+{
+ if (argc == 12) SDL_GL_GetProcAddress("glWhatevah");
+
+ /* Initialize the window */
+ glutInit(&argc, argv);
+ glutInitWindowSize(300, 300);
+ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+
+ glutCreateWindow("es2gears");
+
+ gears_idle();
+ gears_init();
+ gears_draw();
+
+ int result = 1;
+ REPORT_RESULT();
+
+ return 0;
+}
diff --git a/tests/gl_ps.c b/tests/gl_ps.c
index 6ea0e3db..4fa79922 100644
--- a/tests/gl_ps.c
+++ b/tests/gl_ps.c
@@ -115,11 +115,11 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
+
#if !EMSCRIPTEN
glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
#endif
@@ -135,30 +135,30 @@ int main(int argc, char *argv[])
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
-
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -169,25 +169,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
shaders();
// Bind the texture to which subsequent calls refer to
@@ -218,7 +218,7 @@ int main(int argc, char *argv[])
glDisableClientState(GL_VERTEX_ARRAY);
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(3000);
@@ -226,8 +226,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/gl_ps_workaround.c b/tests/gl_ps_workaround.c
deleted file mode 100644
index 1e2a5c41..00000000
--- a/tests/gl_ps_workaround.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*******************************************************************
- * *
- * Using SDL With OpenGL *
- * *
- * Tutorial by Kyle Foley (sdw) *
- * *
- * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL *
- * *
- *******************************************************************/
-
-/*
-THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION
-AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN.
-
-THE ORIGINAL AUTHOR IS KYLE FOLEY.
-
-THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
-OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
-MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
-ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
-RESULTING FROM THE USE, MODIFICATION, OR
-REDISTRIBUTION OF THIS SOFTWARE.
-*/
-
-#if !EMSCRIPTEN
-#define USE_GLEW 1
-#endif
-
-#if USE_GLEW
-#include "GL/glew.h"
-#endif
-
-#include "SDL/SDL.h"
-#include "SDL/SDL_image.h"
-#if !USE_GLEW
-#include "SDL/SDL_opengl.h"
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-void shaders() {
-#if USE_GLEW
- glewInit();
-#endif
-
- GLint ok;
-
- const char *vertexShader = "void main(void) \n"
- "{ \n"
- " gl_Position = ftransform(); \n"
- " gl_TexCoord[0] = gl_MultiTexCoord0; \n"
- " gl_FrontColor = gl_Color; \n"
- "} \n";
- const char *fragmentShader = "uniform sampler2D tex0; \n"
- "void main(void) \n"
- "{ \n"
- " gl_FragColor = gl_Color * texture2D(tex0, gl_TexCoord[0].xy); \n"
- "} \n";
-
- GLuint vs = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vs, 1, &vertexShader, NULL);
- glCompileShader(vs);
- glGetShaderiv(vs, GL_COMPILE_STATUS, &ok);
- assert(ok);
-
- GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fs, 1, &fragmentShader, NULL);
- glCompileShader(fs);
- glGetShaderiv(fs, GL_COMPILE_STATUS, &ok);
- assert(ok);
-
- GLuint program = glCreateProgram();
-
- glAttachShader(program, vs);
- glAttachShader(program, fs);
- glLinkProgram(program);
- glGetProgramiv(program, GL_LINK_STATUS, &ok);
- assert(ok);
-
- glUseProgram(program);
-}
-
-int main(int argc, char *argv[])
-{
- SDL_Surface *screen;
-
- // Slightly different SDL initialization
- if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
- printf("Unable to initialize SDL: %s\n", SDL_GetError());
- return 1;
- }
-
- SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
-
- screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed*
- if ( !screen ) {
- printf("Unable to set video mode: %s\n", SDL_GetError());
- return 1;
- }
-
- // Set the OpenGL state after creating the context with SDL_SetVideoMode
-
- glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
-
- glViewport( 0, 0, 640, 480 );
-
- glMatrixMode( GL_PROJECTION );
- GLfloat matrixData[] = { 2.0/640, 0, 0, 0,
- 0, -2.0/480, 0, 0,
- 0, 0, -1, 0,
- -1, 1, 0, 1 };
- glLoadMatrixf(matrixData); // test loadmatrix
-
- glMatrixMode( GL_MODELVIEW );
- glLoadIdentity();
-
- // Load the OpenGL texture
-
- GLuint texture; // Texture object handle
- SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
- // Check that the image's width is a power of 2
- if ( (surface->w & (surface->w - 1)) != 0 ) {
- printf("warning: image.bmp's width is not a power of 2\n");
- }
-
- // Also check if the height is a power of 2
- if ( (surface->h & (surface->h - 1)) != 0 ) {
- printf("warning: image.bmp's height is not a power of 2\n");
- }
-
- // Have OpenGL generate a texture object handle for us
- glGenTextures( 1, &texture );
-
- // Bind the texture object
- glBindTexture( GL_TEXTURE_2D, texture );
-
- // Set the texture's stretching properties
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
-
- //SDL_LockSurface(surface);
-
- // Add some greyness
- memset(surface->pixels, 0x66, surface->w*surface->h);
-
- // Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
-
- //SDL_UnlockSurface(surface);
- }
- else {
- printf("SDL could not load image.bmp: %s\n", SDL_GetError());
- SDL_Quit();
- return 1;
- }
-
- // Free the SDL_Surface only if it was successfully created
- if ( surface ) {
- SDL_FreeSurface( surface );
- }
-
- // Clear the screen before drawing
- glClear( GL_COLOR_BUFFER_BIT );
-
- shaders();
-
- // Bind the texture to which subsequent calls refer to
- glBindTexture( GL_TEXTURE_2D, texture );
-
- // Use clientside vertex pointers to render two items. In this test we have each
- // attribute in a separate buffer, packed (i.e. stride == 0)
- GLfloat vertexData[] = { 10, 10,
- 300, 10,
- 300, 128,
- 10, 128,
- 410, 10,
- 600, 10,
- 630, 200,
- 310, 250,
- 100, 300,
- 300, 300,
- 300, 400,
- 100, 400 };
- GLfloat textureData[] = { 0, 0,
- 1, 0,
- 1, 1,
- 0, 1,
- 0, 0.5,
- 1, 0.5,
- 1, 1,
- 0.5, 1,
- 0, 0,
- 1, 0,
- 1, 1,
- 0, 1, };
-
- glEnableClientState(GL_TEXTURE_2D); // XXX should be GL_TEXTURE_COORD_ARRAY); // XXX
- glTexCoordPointer(2, GL_FLOAT, 0, textureData);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, vertexData);
-
- glDrawArrays(GL_QUADS, 0, 12);
-
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- SDL_GL_SwapBuffers();
-
-#if !EMSCRIPTEN
- // Wait for 3 seconds to give us a chance to see the image
- SDL_Delay(3000);
-#endif
-
- // Now we can delete the OpenGL texture and close down SDL
- glDeleteTextures( 1, &texture );
-
- SDL_Quit();
-
- return 0;
-}
diff --git a/tests/gl_ps_workaround2.c b/tests/gl_ps_workaround2.c
deleted file mode 100644
index e5bd2fd1..00000000
--- a/tests/gl_ps_workaround2.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*******************************************************************
- * *
- * Using SDL With OpenGL *
- * *
- * Tutorial by Kyle Foley (sdw) *
- * *
- * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL *
- * *
- *******************************************************************/
-
-/*
-THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION
-AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN.
-
-THE ORIGINAL AUTHOR IS KYLE FOLEY.
-
-THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
-OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
-MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
-ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
-RESULTING FROM THE USE, MODIFICATION, OR
-REDISTRIBUTION OF THIS SOFTWARE.
-*/
-
-#if !EMSCRIPTEN
-#define USE_GLEW 1
-#endif
-
-#if USE_GLEW
-#include "GL/glew.h"
-#endif
-
-#include "SDL/SDL.h"
-#include "SDL/SDL_image.h"
-#if !USE_GLEW
-#include "SDL/SDL_opengl.h"
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-void shaders() {
-#if USE_GLEW
- glewInit();
-#endif
-
- GLint ok;
-
- const char *vertexShader = "void main(void) \n"
- "{ \n"
- " gl_Position = ftransform(); \n"
- " gl_TexCoord[0] = gl_MultiTexCoord0; \n"
- " gl_FrontColor = gl_Color; \n"
- "} \n";
- const char *fragmentShader = "uniform sampler2D tex0; \n"
- "void main(void) \n"
- "{ \n"
- " gl_FragColor = gl_Color * texture2D(tex0, gl_TexCoord[0].xy); \n"
- "} \n";
-
- GLuint vs = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vs, 1, &vertexShader, NULL);
- glCompileShader(vs);
- glGetShaderiv(vs, GL_COMPILE_STATUS, &ok);
- assert(ok);
-
- GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fs, 1, &fragmentShader, NULL);
- glCompileShader(fs);
- glGetShaderiv(fs, GL_COMPILE_STATUS, &ok);
- assert(ok);
-
- GLuint program = glCreateProgram();
-
- glAttachShader(program, vs);
- glAttachShader(program, fs);
- glLinkProgram(program);
- glGetProgramiv(program, GL_LINK_STATUS, &ok);
- assert(ok);
-
- glUseProgram(program);
-}
-
-int main(int argc, char *argv[])
-{
- SDL_Surface *screen;
-
- // Slightly different SDL initialization
- if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
- printf("Unable to initialize SDL: %s\n", SDL_GetError());
- return 1;
- }
-
- SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
-
- screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed*
- if ( !screen ) {
- printf("Unable to set video mode: %s\n", SDL_GetError());
- return 1;
- }
-
- // Set the OpenGL state after creating the context with SDL_SetVideoMode
-
- glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
-
- glViewport( 0, 0, 640, 480 );
-
- glMatrixMode( GL_PROJECTION );
- GLfloat matrixData[] = { 2.0/640, 0, 0, 0,
- 0, -2.0/480, 0, 0,
- 0, 0, -1, 0,
- -1, 1, 0, 1 };
- glLoadMatrixf(matrixData); // test loadmatrix
-
- glMatrixMode( GL_MODELVIEW );
- glLoadIdentity();
-
- // Load the OpenGL texture
-
- GLuint texture; // Texture object handle
- SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
- // Check that the image's width is a power of 2
- if ( (surface->w & (surface->w - 1)) != 0 ) {
- printf("warning: image.bmp's width is not a power of 2\n");
- }
-
- // Also check if the height is a power of 2
- if ( (surface->h & (surface->h - 1)) != 0 ) {
- printf("warning: image.bmp's height is not a power of 2\n");
- }
-
- // Have OpenGL generate a texture object handle for us
- glGenTextures( 1, &texture );
-
- // Bind the texture object
- glBindTexture( GL_TEXTURE_2D, texture );
-
- // Set the texture's stretching properties
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
-
- //SDL_LockSurface(surface);
-
- // Add some greyness
- memset(surface->pixels, 0x66, surface->w*surface->h);
-
- // Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
-
- //SDL_UnlockSurface(surface);
- }
- else {
- printf("SDL could not load image.bmp: %s\n", SDL_GetError());
- SDL_Quit();
- return 1;
- }
-
- // Free the SDL_Surface only if it was successfully created
- if ( surface ) {
- SDL_FreeSurface( surface );
- }
-
- // Clear the screen before drawing
- glClear( GL_COLOR_BUFFER_BIT );
-
- shaders();
-
- // Bind the texture to which subsequent calls refer to
- glBindTexture( GL_TEXTURE_2D, texture );
-
- // Use clientside vertex pointers to render two items. In this test we have each
- // attribute in a separate buffer, packed (i.e. stride == 0)
- GLfloat vertexData[] = { 10, 10,
- 300, 10,
- 300, 128,
- 10, 128,
- 410, 10,
- 600, 10,
- 630, 200,
- 310, 250,
- 100, 300,
- 300, 300,
- 300, 400,
- 100, 400 };
- GLfloat textureData[] = { 0, 0,
- 1, 0,
- 1, 1,
- 0, 1,
- 0, 0.5,
- 1, 0.5,
- 1, 1,
- 0.5, 1,
- 0, 0,
- 1, 0,
- 1, 1,
- 0, 1, };
-
- glEnable(GL_TEXTURE_2D); // XXX should be GL_TEXTURE_COORD_ARRAY); and also glEnableClientState! XXX two workarounds here
- glTexCoordPointer(2, GL_FLOAT, 0, textureData);
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, vertexData);
-
- glDrawArrays(GL_QUADS, 0, 12);
-
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- SDL_GL_SwapBuffers();
-
-#if !EMSCRIPTEN
- // Wait for 3 seconds to give us a chance to see the image
- SDL_Delay(3000);
-#endif
-
- // Now we can delete the OpenGL texture and close down SDL
- glDeleteTextures( 1, &texture );
-
- SDL_Quit();
-
- return 0;
-}
diff --git a/tests/glbegin_points.c b/tests/glbegin_points.c
index b28cca4e..9128a4f5 100644
--- a/tests/glbegin_points.c
+++ b/tests/glbegin_points.c
@@ -46,14 +46,12 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -66,30 +64,30 @@ int main(int argc, char *argv[])
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
-
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -100,25 +98,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -151,7 +149,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(3000);
@@ -159,8 +157,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/runner.py b/tests/runner.py
index 720f434e..47c1f1be 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -904,26 +904,26 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows
void interface_clock_changed()
{
- UINT8 m_divshift;
- INT32 m_divisor;
+ UINT8 m_divshift;
+ INT32 m_divisor;
- //INT64 attos = m_attoseconds_per_cycle;
- INT64 attos = 279365114840;
- m_divshift = 0;
- while (attos >= (1UL << 31))
- {
- m_divshift++;
- printf("m_divshift is %i, on %Ld >?= %lu\n", m_divshift, attos, 1UL << 31);
- attos >>= 1;
- }
- m_divisor = attos;
+ //INT64 attos = m_attoseconds_per_cycle;
+ INT64 attos = 279365114840;
+ m_divshift = 0;
+ while (attos >= (1UL << 31))
+ {
+ m_divshift++;
+ printf("m_divshift is %i, on %Ld >?= %lu\n", m_divshift, attos, 1UL << 31);
+ attos >>= 1;
+ }
+ m_divisor = attos;
- printf("m_divisor is %i\n",m_divisor);
+ printf("m_divisor is %i\n",m_divisor);
}
int main() {
- interface_clock_changed();
- return 0;
+ interface_clock_changed();
+ return 0;
}
'''
self.do_run(src, '''m_divshift is 1, on 279365114840 >?= 2147483648
@@ -997,8 +997,8 @@ m_divisor is 1091269979
volatile UINT64 testu64a = 14746250828952703000U;
while ((UINT64)testu32a * (UINT64)bigu32 < testu64a) {
- printf("testu64a is %llu\n", testu64a);
- testu64a /= 2;
+ printf("testu64a is %llu\n", testu64a);
+ testu64a /= 2;
}
return 0;
@@ -1456,28 +1456,28 @@ c5,de,15,8a
quint64 v = strtoull("4433ffeeddccbb00", NULL, 16);
printf("%lld\n", v);
- const string string64bitInt = "4433ffeeddccbb00";
- stringstream s(string64bitInt);
- quint64 int64bitInt = 0;
+ const string string64bitInt = "4433ffeeddccbb00";
+ stringstream s(string64bitInt);
+ quint64 int64bitInt = 0;
printf("1\n");
- s >> hex >> int64bitInt;
+ s >> hex >> int64bitInt;
printf("2\n");
- stringstream out;
- out << hex << qbswap(int64bitInt);
+ stringstream out;
+ out << hex << qbswap(int64bitInt);
- cout << out.str() << endl;
- cout << hex << int64bitInt << endl;
- cout << string64bitInt << endl;
+ cout << out.str() << endl;
+ cout << hex << int64bitInt << endl;
+ cout << string64bitInt << endl;
- if (out.str() != "bbccddeeff3344")
- {
- cout << "Failed!" << endl;
- }
- else
- {
- cout << "Succeeded!" << endl;
- }
+ if (out.str() != "bbccddeeff3344")
+ {
+ cout << "Failed!" << endl;
+ }
+ else
+ {
+ cout << "Succeeded!" << endl;
+ }
return 0;
}
@@ -4030,15 +4030,15 @@ def process(filename):
// see related things in openjpeg
typedef struct opj_mqc_state {
- unsigned int qeval;
- int mps;
- struct opj_mqc_state *nmps;
- struct opj_mqc_state *nlps;
+ unsigned int qeval;
+ int mps;
+ struct opj_mqc_state *nmps;
+ struct opj_mqc_state *nlps;
} opj_mqc_state_t;
static opj_mqc_state_t mqc_states[2] = {
- {0x5600, 0, &mqc_states[2], &mqc_states[3]},
- {0x5602, 1, &mqc_states[3], &mqc_states[2]},
+ {0x5600, 0, &mqc_states[2], &mqc_states[3]},
+ {0x5602, 1, &mqc_states[3], &mqc_states[2]},
};
int main() {
@@ -4533,6 +4533,8 @@ The current type of b is: 9
self.do_run(src, '*1*', force_c=True)
def test_strtoll_hex(self):
+ if self.emcc_args is None: return self.skip('requires emcc')
+
# tests strtoll for hex strings (0x...)
src = r'''
#include <stdio.h>
@@ -4559,6 +4561,8 @@ The current type of b is: 9
self.do_run(src, '111111')
def test_strtoll_dec(self):
+ if self.emcc_args is None: return self.skip('requires emcc')
+
# tests strtoll for decimal strings (0x...)
src = r'''
#include <stdio.h>
@@ -4585,6 +4589,8 @@ The current type of b is: 9
self.do_run(src, '111111')
def test_strtoll_bin(self):
+ if self.emcc_args is None: return self.skip('requires emcc')
+
# tests strtoll for binary strings (0x...)
src = r'''
#include <stdio.h>
@@ -4606,6 +4612,8 @@ The current type of b is: 9
self.do_run(src, '111')
def test_strtoll_oct(self):
+ if self.emcc_args is None: return self.skip('requires emcc')
+
# tests strtoll for decimal strings (0x...)
src = r'''
#include <stdio.h>
@@ -4807,25 +4815,25 @@ The current type of b is: 9
typedef struct
{
- int (*f)(void *);
- void *d;
- char s[16];
+ int (*f)(void *);
+ void *d;
+ char s[16];
} LMEXFunctionStruct;
int f(void *user)
{
- return 0;
+ return 0;
}
static LMEXFunctionStruct const a[] =
{
- {f, (void *)(int)'a', "aa"}
+ {f, (void *)(int)'a', "aa"}
};
int main()
{
printf("ok\n");
- return a[0].f(a[0].d);
+ return a[0].f(a[0].d);
}
'''
self.do_run(src, 'ok\n')
@@ -6824,7 +6832,7 @@ def process(filename):
printf("f_blocks: %lu\n", s.f_blocks);
printf("f_bfree: %lu\n", s.f_bfree);
printf("f_bavail: %lu\n", s.f_bavail);
- printf("f_files: %lu\n", s.f_files);
+ printf("f_files: %d\n", s.f_files > 5);
printf("f_ffree: %lu\n", s.f_ffree);
printf("f_favail: %lu\n", s.f_favail);
printf("f_fsid: %lu\n", s.f_fsid);
@@ -6842,7 +6850,7 @@ def process(filename):
f_blocks: 1000000
f_bfree: 500000
f_bavail: 500000
- f_files: 10
+ f_files: 1
f_ffree: 1000000
f_favail: 1000000
f_fsid: 42
@@ -10307,6 +10315,8 @@ f.close()
assert not os.path.exists('a.out') and not os.path.exists('a.exe'), 'Must not leave unneeded linker stubs'
def test_symlink(self):
+ if os.name == 'nt':
+ return self.skip('Windows FS does not need to be tested for symlinks support, since it does not have them.')
open(os.path.join(self.get_dir(), 'foobar.xxx'), 'w').write('int main(){ return 0; }')
os.symlink(os.path.join(self.get_dir(), 'foobar.xxx'), os.path.join(self.get_dir(), 'foobar.c'))
Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'foobar.c'), '-o', os.path.join(self.get_dir(), 'foobar')], stdout=PIPE, stderr=PIPE).communicate()
@@ -10461,8 +10471,8 @@ f.close()
#define _TESTA_H_
class TestA {
- public:
- TestA();
+ public:
+ TestA();
};
#endif
@@ -10472,8 +10482,8 @@ f.close()
#define _TESTB_H_
class TestB {
- public:
- TestB();
+ public:
+ TestB();
};
#endif
@@ -10483,7 +10493,7 @@ f.close()
#include <testa.h>
TestA::TestA() {
- printf("TestA\n");
+ printf("TestA\n");
}
''')
open('testb.cpp', 'w').write(r'''
@@ -10493,8 +10503,8 @@ f.close()
/*
*/
TestB::TestB() {
- printf("TestB\n");
- TestA* testa = new TestA();
+ printf("TestB\n");
+ TestA* testa = new TestA();
}
''')
open('main.cpp', 'w').write(r'''
@@ -10505,9 +10515,9 @@ f.close()
/*
*/
int main(int argc, char** argv) {
- printf("Main\n");
- TestA* testa = new TestA();
- TestB* testb = new TestB();
+ printf("Main\n");
+ TestA* testa = new TestA();
+ TestB* testb = new TestB();
}
''')
@@ -12436,6 +12446,9 @@ elif 'browser' in str(sys.argv):
self.run_browser('something.html', 'You should see animating gears.', '/report_gl_result?true')
assert ('var GLEmulation' in open(self.in_dir('something.html')).read()) == emulation, "emulation code should be added when asked for"
+ def test_fulles2_sdlproc(self):
+ self.btest('full_es2_sdlproc.c', '1', args=['-s', 'GL_TESTING=1', '-DHAVE_BUILTIN_SINCOS', '-s', 'FULL_ES2=1'])
+
def test_glgears_deriv(self):
self.reftest(path_from_root('tests', 'gears.png'))
Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_gles_deriv.c'), '-o', 'something.html', '-s', 'GL_TESTING=1',
@@ -12549,14 +12562,6 @@ elif 'browser' in str(sys.argv):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('gl_ps_packed.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png'])
- def test_gl_ps_workaround(self):
- shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('gl_ps_workaround.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png'])
-
- def test_gl_ps_workaround2(self):
- shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
- self.btest('gl_ps_workaround2.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png'])
-
def test_gl_ps_strides(self):
shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
self.btest('gl_ps_strides.c', reference='gl_ps_strides.png', args=['--preload-file', 'screenshot.png'])
@@ -14005,7 +14010,7 @@ if __name__ == '__main__':
which = map(lambda mode: mode+'.'+test, test_modes)
else:
which = [which]
-
+
print >> sys.stderr, ','.join(which)
for test in which:
print >> sys.stderr, 'will skip "%s"' % test
diff --git a/tests/s3tc.c b/tests/s3tc.c
index c2736feb..16ee783f 100644
--- a/tests/s3tc.c
+++ b/tests/s3tc.c
@@ -63,14 +63,12 @@ int main(int argc, char *argv[])
const char *exts = (const char *)glGetString(GL_EXTENSIONS);
assert(hasext(exts, "GL_ARB_texture_compression"));
assert(hasext(exts, "GL_EXT_texture_compression_s3tc"));
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -110,7 +108,7 @@ int main(int argc, char *argv[])
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -143,7 +141,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(1500);
@@ -151,8 +149,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/s3tc_crunch.c b/tests/s3tc_crunch.c
index 57974109..90ed02d9 100644
--- a/tests/s3tc_crunch.c
+++ b/tests/s3tc_crunch.c
@@ -63,14 +63,12 @@ int main(int argc, char *argv[])
const char *exts = (const char *)glGetString(GL_EXTENSIONS);
assert(hasext(exts, "GL_ARB_texture_compression"));
assert(hasext(exts, "GL_EXT_texture_compression_s3tc"));
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -158,7 +156,7 @@ int main(int argc, char *argv[])
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -195,7 +193,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(1500);
@@ -203,8 +201,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/sdl_fog_density.c b/tests/sdl_fog_density.c
index 95773419..cab6a4d2 100644
--- a/tests/sdl_fog_density.c
+++ b/tests/sdl_fog_density.c
@@ -47,14 +47,12 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -63,33 +61,33 @@ int main(int argc, char *argv[])
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1000, 1000 );
-
+
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
-
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -100,25 +98,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -148,9 +146,7 @@ int main(int argc, char *argv[])
glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 1 );
glEnd();
-#if !EMSCRIPTEN
glDisable(GL_TEXTURE_2D);
-#endif
glColor3ub(90, 255, 255);
glBegin( GL_QUADS );
@@ -168,7 +164,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(30000);
@@ -176,8 +172,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/sdl_fog_exp2.c b/tests/sdl_fog_exp2.c
index a09a5e3d..dba0c708 100644
--- a/tests/sdl_fog_exp2.c
+++ b/tests/sdl_fog_exp2.c
@@ -47,14 +47,12 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -63,33 +61,33 @@ int main(int argc, char *argv[])
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1000, 1000 );
-
+
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
-
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -100,25 +98,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -149,9 +147,7 @@ int main(int argc, char *argv[])
glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 1 );
glEnd();
-#if !EMSCRIPTEN
glDisable(GL_TEXTURE_2D);
-#endif
glColor3ub(90, 255, 255);
glBegin( GL_QUADS );
@@ -169,7 +165,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(30000);
@@ -177,8 +173,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/sdl_fog_linear.c b/tests/sdl_fog_linear.c
index 8fc18b7c..f0805650 100644
--- a/tests/sdl_fog_linear.c
+++ b/tests/sdl_fog_linear.c
@@ -47,14 +47,12 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -63,33 +61,33 @@ int main(int argc, char *argv[])
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1000, 1000 );
-
+
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
-
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -100,25 +98,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -150,9 +148,7 @@ int main(int argc, char *argv[])
glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 1 );
glEnd();
-#if !EMSCRIPTEN
glDisable(GL_TEXTURE_2D);
-#endif
glColor3ub(90, 255, 255);
glBegin( GL_QUADS );
@@ -170,7 +166,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(30000);
@@ -178,8 +174,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/sdl_fog_negative.c b/tests/sdl_fog_negative.c
index 2d589a47..1ede63a7 100644
--- a/tests/sdl_fog_negative.c
+++ b/tests/sdl_fog_negative.c
@@ -47,14 +47,12 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -63,33 +61,33 @@ int main(int argc, char *argv[])
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1000, 1000 );
-
+
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
-
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -100,25 +98,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -147,9 +145,7 @@ int main(int argc, char *argv[])
glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, -1 );
glEnd();
-#if !EMSCRIPTEN
glDisable(GL_TEXTURE_2D);
-#endif
glColor3ub(90, 255, 255);
glBegin( GL_QUADS );
@@ -167,7 +163,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(30000);
@@ -175,8 +171,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/sdl_fog_simple.c b/tests/sdl_fog_simple.c
index be023593..6c052bf5 100644
--- a/tests/sdl_fog_simple.c
+++ b/tests/sdl_fog_simple.c
@@ -47,14 +47,10 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
glViewport( 0, 0, 640, 480 );
@@ -63,33 +59,38 @@ int main(int argc, char *argv[])
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1000, 1000 );
-
+
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
-
+
+ // Delay Enable to after MatrixMode to assure we've activated
+ // immediate mode. Otherwise, we don't properly record that
+ // TEXTURE_2D is enabled for imm mode emulation.
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -100,25 +101,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -147,9 +148,7 @@ int main(int argc, char *argv[])
glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 1 );
glEnd();
-#if !EMSCRIPTEN
glDisable(GL_TEXTURE_2D);
-#endif
glColor3ub(90, 255, 255);
glBegin( GL_QUADS );
@@ -167,7 +166,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(30000);
@@ -175,8 +174,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/sdl_ogl.c b/tests/sdl_ogl.c
index 6b6a5b4a..e7071dcd 100644
--- a/tests/sdl_ogl.c
+++ b/tests/sdl_ogl.c
@@ -46,14 +46,12 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -62,33 +60,33 @@ int main(int argc, char *argv[])
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1, 1 );
-
+
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
-
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -99,25 +97,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -140,9 +138,7 @@ int main(int argc, char *argv[])
glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 );
glEnd();
-#if !EMSCRIPTEN
glDisable(GL_TEXTURE_2D);
-#endif
glColor3ub(90, 255, 255);
glBegin( GL_QUADS );
@@ -160,7 +156,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(3000);
@@ -168,8 +164,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/sdl_ogl_defaultMatrixMode.c b/tests/sdl_ogl_defaultMatrixMode.c
index 0da0a326..eec2a831 100644
--- a/tests/sdl_ogl_defaultMatrixMode.c
+++ b/tests/sdl_ogl_defaultMatrixMode.c
@@ -46,14 +46,12 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -66,30 +64,30 @@ int main(int argc, char *argv[])
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1, 1 );
-
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -100,25 +98,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -141,9 +139,7 @@ int main(int argc, char *argv[])
glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, 0 );
glEnd();
-#if !EMSCRIPTEN
glDisable(GL_TEXTURE_2D);
-#endif
glColor3ub(90, 255, 255);
glBegin( GL_QUADS );
@@ -161,7 +157,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(3000);
@@ -169,8 +165,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/tests/sdl_ogl_p.c b/tests/sdl_ogl_p.c
index fcc53a40..1889d926 100644
--- a/tests/sdl_ogl_p.c
+++ b/tests/sdl_ogl_p.c
@@ -46,14 +46,12 @@ int main(int argc, char *argv[])
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
-
+
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
-
-#if !EMSCRIPTEN
- glEnable( GL_TEXTURE_2D ); // Need this to display a texture XXX unnecessary in OpenGL ES 2.0/WebGL
-#endif
+
+ glEnable( GL_TEXTURE_2D ); // Needed when we're using the fixed-function pipeline.
glViewport( 0, 0, 640, 480 );
@@ -66,30 +64,30 @@ int main(int argc, char *argv[])
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
-
+
// Load the OpenGL texture
GLuint texture; // Texture object handle
SDL_Surface *surface; // Gives us the information to make the texture
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
-
+
+ if ( (surface = IMG_Load("screenshot.png")) ) {
+
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
-
+
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
-
+
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
-
+
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
-
+
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
@@ -100,25 +98,25 @@ int main(int argc, char *argv[])
memset(surface->pixels, 0x66, surface->w*surface->h);
// Edit the texture object's image data using the information SDL_Surface gives us
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
//SDL_UnlockSurface(surface);
- }
+ }
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
- }
-
+ }
+
// Free the SDL_Surface only if it was successfully created
- if ( surface ) {
+ if ( surface ) {
SDL_FreeSurface( surface );
}
-
+
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
-
+
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
@@ -151,7 +149,7 @@ int main(int argc, char *argv[])
glEnd();
SDL_GL_SwapBuffers();
-
+
#if !EMSCRIPTEN
// Wait for 3 seconds to give us a chance to see the image
SDL_Delay(3000);
@@ -159,8 +157,8 @@ int main(int argc, char *argv[])
// Now we can delete the OpenGL texture and close down SDL
glDeleteTextures( 1, &texture );
-
+
SDL_Quit();
-
+
return 0;
}
diff --git a/third_party/lzma.js/lzip/Makefile b/third_party/lzma.js/lzip/Makefile
index ca6a6ef7..8a5baee3 100644
--- a/third_party/lzma.js/lzip/Makefile
+++ b/third_party/lzma.js/lzip/Makefile
@@ -16,7 +16,8 @@ datadir = $(prefix)/share
infodir = $(datadir)/info
mandir = $(datadir)/man
sysconfdir = $(prefix)/etc
-CPPFLAGS = -DDECODER_ONLY=$(DECODER_ONLY)
+CXX = g++
+CPPFLAGS =
CXXFLAGS = -Wall -W -O2
LDFLAGS =
@@ -27,16 +28,16 @@ INSTALL_DATA = $(INSTALL) -p -m 644
INSTALL_DIR = $(INSTALL) -d -m 755
SHELL = /bin/sh
-objs = decoder.o encoder.o fast_encoder.o main.o
-recobjs = decoder.o lziprecover.o
-unzobjs = unzcrash.o
+objs = arg_parser.o decoder.o encoder.o fast_encoder.o main.o
+recobjs = arg_parser.o decoder.o lziprecover.o
+unzobjs = arg_parser.o unzcrash.o
.PHONY : all install install-info install-man install-strip \
uninstall uninstall-info uninstall-man \
doc info man check dist clean distclean
-all : $(progname)
+all : $(progname) lziprecover
$(progname) : $(objs)
$(CXX) $(LDFLAGS) -o $@ $(objs)
@@ -63,12 +64,13 @@ unzcrash.o : testsuite/unzcrash.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
$(objs) : Makefile
+arg_parser.o : arg_parser.h
decoder.o : lzip.h decoder.h
encoder.o : lzip.h encoder.h
fast_encoder.o : lzip.h encoder.h fast_encoder.h
-main.o : lzip.h decoder.h encoder.h fast_encoder.h
-lziprecover.o : lzip.h decoder.h Makefile
-unzcrash.o : Makefile
+main.o : arg_parser.h lzip.h decoder.h encoder.h fast_encoder.h
+lziprecover.o : arg_parser.h lzip.h decoder.h Makefile
+unzcrash.o : arg_parser.h Makefile
doc : info man
diff --git a/tools/shared.py b/tools/shared.py
index 7d956293..799a5bbe 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -295,7 +295,7 @@ def check_node_version():
# we re-check sanity when the settings are changed)
# We also re-check sanity and clear the cache when the version changes
-EMSCRIPTEN_VERSION = '1.4.3'
+EMSCRIPTEN_VERSION = '1.4.7'
def generate_sanity():
return EMSCRIPTEN_VERSION + '|' + get_llvm_target()