aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc3
-rwxr-xr-xemlibtool11
-rw-r--r--emlibtool.bat2
-rw-r--r--src/jsifier.js3
-rw-r--r--src/library.js70
-rw-r--r--src/library_gl.js15
-rw-r--r--src/library_openal.js17
-rw-r--r--src/parseTools.js9
-rw-r--r--tests/gl_vertex_buffer.c195
-rw-r--r--tests/gl_vertex_buffer.pngbin0 -> 47668 bytes
-rw-r--r--tests/gl_vertex_buffer_pre.c177
-rw-r--r--tests/gl_vertex_buffer_pre.pngbin0 -> 83534 bytes
-rw-r--r--tests/test_browser.py6
-rw-r--r--tests/test_core.py137
-rw-r--r--tools/shared.py28
15 files changed, 619 insertions, 54 deletions
diff --git a/emcc b/emcc
index 93621a83..958ed7cd 100755
--- a/emcc
+++ b/emcc
@@ -1125,6 +1125,9 @@ try:
else:
logging.debug('using response file for EXPORTED_FUNCTIONS, make sure it includes _malloc and _free')
+ if shared.Settings.ASM_JS and shared.Settings.DLOPEN_SUPPORT:
+ assert shared.Settings.DISABLE_EXCEPTION_CATCHING, 'no exceptions support with dlopen in asm yet'
+
## Compile source code to bitcode
logging.debug('compiling to bitcode')
diff --git a/emlibtool b/emlibtool
deleted file mode 100755
index 1eb18edc..00000000
--- a/emlibtool
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python2
-
-'''
-This is a helper script. See emcc.
-'''
-
-import os, sys
-from tools import shared
-
-raise Exception('TODO: emlibtool')
-
diff --git a/emlibtool.bat b/emlibtool.bat
deleted file mode 100644
index 4ea705be..00000000
--- a/emlibtool.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-@echo off
-python "%~dp0\emlibtool" %* \ No newline at end of file
diff --git a/src/jsifier.js b/src/jsifier.js
index 8592364d..f5682a1b 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -338,6 +338,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// External variables in shared libraries should not be declared as
// they would shadow similarly-named globals in the parent, so do nothing here.
if (BUILD_AS_SHARED_LIB) return ret;
+ if (SIDE_MODULE) return [];
// Library items need us to emit something, but everything else requires nothing.
if (!LibraryManager.library[item.ident.slice(1)]) return ret;
}
@@ -1408,7 +1409,7 @@ function JSify(data, functionsOnly, givenFunctions) {
var extCall = false;
if (ASM_JS && funcData.setjmpTable) forceByPointer = true; // in asm.js mode, we must do an invoke for each call
- if (ASM_JS && DLOPEN_SUPPORT && !invoke) extCall = true; // go out, to be able to access other modules TODO: optimize
+ if (ASM_JS && DLOPEN_SUPPORT && !invoke && !funcData.setjmpTable) extCall = true; // go out, to be able to access other modules TODO: optimize
ident = Variables.resolveAliasToIdent(ident);
var shortident = ident.slice(1);
diff --git a/src/library.js b/src/library.js
index 7fe11433..f3c3c1ec 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4279,9 +4279,11 @@ LibraryManager.library = {
__cxa_guard_release: function() {},
__cxa_guard_abort: function() {},
+#if USE_TYPED_ARRAYS != 2
_ZTVN10__cxxabiv119__pointer_type_infoE: [0], // is a pointer
_ZTVN10__cxxabiv117__class_type_infoE: [1], // no inherited classes
_ZTVN10__cxxabiv120__si_class_type_infoE: [2], // yes inherited classes
+#endif
// Exceptions
__cxa_allocate_exception: function(size) {
@@ -4663,20 +4665,28 @@ LibraryManager.library = {
cos: 'Math.cos',
cosf: 'Math.cos',
+ cosl: 'Math.cos',
sin: 'Math.sin',
sinf: 'Math.sin',
+ sinl: 'Math.sin',
tan: 'Math.tan',
tanf: 'Math.tan',
+ tanl: 'Math.tan',
acos: 'Math.acos',
acosf: 'Math.acos',
+ acosl: 'Math.acos',
asin: 'Math.asin',
asinf: 'Math.asin',
+ asinl: 'Math.asin',
atan: 'Math.atan',
atanf: 'Math.atan',
+ atanl: 'Math.atan',
atan2: 'Math.atan2',
atan2f: 'Math.atan2',
+ atan2l: 'Math.atan2',
exp: 'Math.exp',
expf: 'Math.exp',
+ expl: 'Math.exp',
// The erf and erfc functions are inspired from
// http://www.digitalmars.com/archives/cplusplus/3634.html
@@ -4712,7 +4722,8 @@ LibraryManager.library = {
} while (Math.abs(q1 - q2) / q2 > MATH_TOLERANCE);
return (ONE_SQRTPI * Math.exp(- x * x) * q2);
},
- erfcf: 'erfcf',
+ erfcf: 'erfc',
+ erfcl: 'erfc',
erf__deps: ['erfc'],
erf: function(x) {
var MATH_TOLERANCE = 1E-12;
@@ -4736,6 +4747,7 @@ LibraryManager.library = {
return (TWO_SQRTPI * sum);
},
erff: 'erf',
+ erfl: 'erf',
log: 'Math.log',
logf: 'Math.log',
logl: 'Math.log',
@@ -4824,6 +4836,7 @@ LibraryManager.library = {
return __reallyNegative(a) === __reallyNegative(b) ? a : -a;
},
copysignf: 'copysign',
+ copysignl: 'copysign',
__signbit__deps: ['copysign'],
__signbit: function(x) {
// We implement using copysign so that we get support
@@ -4836,56 +4849,70 @@ LibraryManager.library = {
return Math.sqrt(a*a + b*b);
},
hypotf: 'hypot',
+ hypotl: 'hypot',
sinh: function(x) {
var p = Math.pow(Math.E, x);
return (p - (1 / p)) / 2;
},
sinhf: 'sinh',
+ sinhl: 'sinh',
cosh: function(x) {
var p = Math.pow(Math.E, x);
return (p + (1 / p)) / 2;
},
coshf: 'cosh',
+ coshl: 'cosh',
tanh__deps: ['sinh', 'cosh'],
tanh: function(x) {
return _sinh(x) / _cosh(x);
},
tanhf: 'tanh',
+ tanhl: 'tanh',
asinh: function(x) {
return Math.log(x + Math.sqrt(x * x + 1));
},
asinhf: 'asinh',
+ asinhl: 'asinh',
acosh: function(x) {
return Math.log(x * 1 + Math.sqrt(x * x - 1));
},
acoshf: 'acosh',
+ acoshl: 'acosh',
atanh: function(x) {
return Math.log((1 + x) / (1 - x)) / 2;
},
atanhf: 'atanh',
+ atanhl: 'atanh',
exp2: function(x) {
return Math.pow(2, x);
},
exp2f: 'exp2',
+ exp2l: 'exp2',
expm1: function(x) {
return Math.exp(x) - 1;
},
expm1f: 'expm1',
+ expm1l: 'expm1',
round: function(x) {
return (x < 0) ? -Math.round(-x) : Math.round(x);
},
roundf: 'round',
+ roundl: 'round',
lround: 'round',
lroundf: 'round',
+ lroundl: 'round',
llround: 'round',
llroundf: 'round',
+ llroundl: 'round',
rint: function(x) {
if (Math.abs(x % 1) !== 0.5) return Math.round(x);
return x + x % 2 + ((x < 0) ? 1 : -1);
},
rintf: 'rint',
+ rintl: 'rint',
lrint: 'rint',
lrintf: 'rint',
+ lrintl: 'rint',
#if USE_TYPED_ARRAYS == 2
llrint: function(x) {
x = (x < 0) ? -Math.round(-x) : Math.round(x);
@@ -4895,50 +4922,63 @@ LibraryManager.library = {
llrint: 'rint',
#endif
llrintf: 'llrint',
+ llrintl: 'llrint',
nearbyint: 'rint',
nearbyintf: 'rint',
+ nearbyintl: 'rint',
trunc: function(x) {
return (x < 0) ? Math.ceil(x) : Math.floor(x);
},
truncf: 'trunc',
+ truncl: 'trunc',
fdim: function(x, y) {
return (x > y) ? x - y : 0;
},
fdimf: 'fdim',
+ fdiml: 'fdim',
fmax: function(x, y) {
return isNaN(x) ? y : isNaN(y) ? x : Math.max(x, y);
},
fmaxf: 'fmax',
+ fmaxl: 'fmax',
fmin: function(x, y) {
return isNaN(x) ? y : isNaN(y) ? x : Math.min(x, y);
},
fminf: 'fmin',
+ fminl: 'fmin',
fma: function(x, y, z) {
return x * y + z;
},
fmaf: 'fma',
+ fmal: 'fma',
fmod: function(x, y) {
return x % y;
},
fmodf: 'fmod',
+ fmodl: 'fmod',
remainder: 'fmod',
remainderf: 'fmod',
+ remainderl: 'fmod',
log10: function(x) {
return Math.log(x) / Math.LN10;
},
log10f: 'log10',
+ log10l: 'log10',
log1p: function(x) {
return Math.log(1 + x);
},
log1pf: 'log1p',
+ log1pl: 'log1p',
log2: function(x) {
return Math.log(x) / Math.LN2;
},
log2f: 'log2',
+ log2l: 'log2',
nan: function(x) {
return NaN;
},
nanf: 'nan',
+ nanl: 'nan',
sincos: function(x, sine, cosine) {
var sineVal = Math.sin(x),
@@ -4946,6 +4986,7 @@ LibraryManager.library = {
{{{ makeSetValue('sine', '0', 'sineVal', 'double') }}};
{{{ makeSetValue('cosine', '0', 'cosineVal', 'double') }}};
},
+ sincosl: 'sincos',
sincosf: function(x, sine, cosine) {
var sineVal = Math.sin(x),
@@ -5302,8 +5343,8 @@ LibraryManager.library = {
['i32', 'tm_zone']]),
// Statically allocated time struct.
__tm_current: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)',
- // Statically allocated timezone strings.
- __tm_timezones: {},
+ // Statically allocated timezone string. We only use GMT as a timezone.
+ __tm_timezone: 'allocate(intArrayFromString("GMT"), "i8", ALLOC_STATIC)',
// Statically allocated time strings.
__tm_formatted: 'allocate({{{ Runtime.QUANTUM_SIZE }}}*26, "i8", ALLOC_STATIC)',
@@ -5331,7 +5372,7 @@ LibraryManager.library = {
return _gmtime_r(time, ___tm_current);
},
- gmtime_r__deps: ['__tm_struct_layout', '__tm_timezones'],
+ gmtime_r__deps: ['__tm_struct_layout', '__tm_timezone'],
gmtime_r: function(time, tmPtr) {
var date = new Date({{{ makeGetValue('time', 0, 'i32') }}}*1000);
var offsets = ___tm_struct_layout;
@@ -5353,12 +5394,7 @@ LibraryManager.library = {
start.setUTCMilliseconds(0);
var yday = Math.floor((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
{{{ makeSetValue('tmPtr', 'offsets.tm_yday', 'yday', 'i32') }}}
-
- var timezone = "GMT";
- if (!(timezone in ___tm_timezones)) {
- ___tm_timezones[timezone] = allocate(intArrayFromString(timezone), 'i8', ALLOC_NORMAL);
- }
- {{{ makeSetValue('tmPtr', 'offsets.tm_zone', '___tm_timezones[timezone]', 'i32') }}}
+ {{{ makeSetValue('tmPtr', 'offsets.tm_zone', '___tm_timezone', 'i32') }}}
return tmPtr;
},
@@ -5377,7 +5413,7 @@ LibraryManager.library = {
return _localtime_r(time, ___tm_current);
},
- localtime_r__deps: ['__tm_struct_layout', '__tm_timezones', 'tzset'],
+ localtime_r__deps: ['__tm_struct_layout', '__tm_timezone', 'tzset'],
localtime_r: function(time, tmPtr) {
_tzset();
var offsets = ___tm_struct_layout;
@@ -5398,11 +5434,7 @@ LibraryManager.library = {
var dst = Number(start.getTimezoneOffset() != date.getTimezoneOffset());
{{{ makeSetValue('tmPtr', 'offsets.tm_isdst', 'dst', 'i32') }}}
- var timezone = 'GMT'; // XXX do not rely on browser timezone info, it is very unpredictable | date.toString().match(/\(([A-Z]+)\)/)[1];
- if (!(timezone in ___tm_timezones)) {
- ___tm_timezones[timezone] = allocate(intArrayFromString(timezone), 'i8', ALLOC_NORMAL);
- }
- {{{ makeSetValue('tmPtr', 'offsets.tm_zone', '___tm_timezones[timezone]', 'i32') }}}
+ {{{ makeSetValue('tmPtr', 'offsets.tm_zone', '___tm_timezone', 'i32') }}}
return tmPtr;
},
@@ -6084,7 +6116,7 @@ LibraryManager.library = {
// int clock_gettime(clockid_t clk_id, struct timespec *tp);
var now = Date.now();
{{{ makeSetValue('tp', '___timespec_struct_layout.tv_sec', 'Math.floor(now/1000)', 'i32') }}}; // seconds
- {{{ makeSetValue('tp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}}; // nanoseconds - not supported
+ {{{ makeSetValue('tp', '___timespec_struct_layout.tv_nsec', '(now % 1000) * 1000 * 1000', 'i32') }}}; // nanoseconds (really milliseconds)
return 0;
},
clock_settime: function(clk_id, tp) {
@@ -6096,7 +6128,7 @@ LibraryManager.library = {
clock_getres: function(clk_id, res) {
// int clock_getres(clockid_t clk_id, struct timespec *res);
{{{ makeSetValue('res', '___timespec_struct_layout.tv_sec', '1', 'i32') }}}
- {{{ makeSetValue('res', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}}
+ {{{ makeSetValue('res', '___timespec_struct_layout.tv_nsec', '1000 * 1000', 'i32') }}} // resolution is milliseconds
return 0;
},
@@ -7405,7 +7437,7 @@ LibraryManager.library = {
var aliasesBuf = _malloc(4);
{{{ makeSetValue('aliasesBuf', '0', '0', 'i8*') }}}
{{{ makeSetValue('ret', '___hostent_struct_layout.h_aliases', 'aliasesBuf', 'i8**') }}}
- var afinet = {{{ cDefine("AF_INET") }}};
+ var afinet = {{{ cDefine('AF_INET') }}};
{{{ makeSetValue('ret', '___hostent_struct_layout.h_addrtype', 'afinet', 'i32') }}}
{{{ makeSetValue('ret', '___hostent_struct_layout.h_length', '4', 'i32') }}}
var addrListBuf = _malloc(12);
diff --git a/src/library_gl.js b/src/library_gl.js
index c134ad97..16ea5531 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -657,6 +657,20 @@ var LibraryGL = {
glBufferData__sig: 'viiii',
glBufferData: function(target, size, data, usage) {
+ switch (usage) { // fix usages, WebGL only has *_DRAW
+ case 0x88E1: // GL_STREAM_READ
+ case 0x88E2: // GL_STREAM_COPY
+ usage = 0x88E0; // GL_STREAM_DRAW
+ break;
+ case 0x88E5: // GL_STATIC_READ
+ case 0x88E6: // GL_STATIC_COPY
+ usage = 0x88E4; // GL_STATIC_DRAW
+ break;
+ case 0x88E9: // GL_DYNAMIC_READ
+ case 0x88EA: // GL_DYNAMIC_COPY
+ usage = 0x88E8; // GL_DYNAMIC_DRAW
+ break;
+ }
Module.ctx.bufferData(target, HEAPU8.subarray(data, data+size), usage);
},
@@ -3398,6 +3412,7 @@ var LibraryGL = {
// does not work for glBegin/End, where we generate renderer components dynamically and then
// disable them ourselves, but it does help with glDrawElements/Arrays.
if (!this.modifiedClientAttributes) {
+ GL.immediate.vertexCounter = (GL.immediate.stride * count) / 4; // XXX assuming float
return;
}
this.modifiedClientAttributes = false;
diff --git a/src/library_openal.js b/src/library_openal.js
index dea986f3..e8a2e223 100644
--- a/src/library_openal.js
+++ b/src/library_openal.js
@@ -8,12 +8,6 @@ var LibraryOpenAL = {
QUEUE_INTERVAL: 25,
QUEUE_LOOKAHEAD: 100,
- getCurrentTime: function(context) {
- // currentTime is frozen during execution, use performance timers to
- // emulate the current time at call time
- return (window['performance']['now']() - context.startTime) / 1000.0;
- },
-
updateSources: function(context) {
for (var i = 0; i < context.src.length; i++) {
AL.updateSource(context.src[i]);
@@ -28,7 +22,7 @@ var LibraryOpenAL = {
return;
}
- var currentTime = AL.getCurrentTime(AL.currentContext);
+ var currentTime = AL.currentContext.ctx.currentTime;
var startTime = src.bufferPosition;
for (var i = src.buffersPlayed; i < src.queue.length; i++) {
@@ -79,7 +73,7 @@ var LibraryOpenAL = {
if (src.state !== 0x1013 /* AL_PAUSED */) {
src.state = 0x1012 /* AL_PLAYING */;
// Reset our position.
- src.bufferPosition = AL.getCurrentTime(AL.currentContext);
+ src.bufferPosition = AL.currentContext.ctx.currentTime;
src.buffersPlayed = 0;
#if OPENAL_DEBUG
console.log('setSourceState resetting and playing source ' + idx);
@@ -87,7 +81,7 @@ var LibraryOpenAL = {
} else {
src.state = 0x1012 /* AL_PLAYING */;
// Use the current offset from src.bufferPosition to resume at the correct point.
- src.bufferPosition = AL.getCurrentTime(AL.currentContext) - src.bufferPosition;
+ src.bufferPosition = AL.currentContext.ctx.currentTime - src.bufferPosition;
#if OPENAL_DEBUG
console.log('setSourceState resuming source ' + idx + ' at ' + src.bufferPosition.toFixed(4));
#endif
@@ -98,7 +92,7 @@ var LibraryOpenAL = {
if (src.state === 0x1012 /* AL_PLAYING */) {
src.state = 0x1013 /* AL_PAUSED */;
// Store off the current offset to restore with on resume.
- src.bufferPosition = AL.getCurrentTime(AL.currentContext) - src.bufferPosition;
+ src.bufferPosition = AL.currentContext.ctx.currentTime - src.bufferPosition;
AL.stopSourceQueue(src);
#if OPENAL_DEBUG
console.log('setSourceState pausing source ' + idx + ' at ' + src.bufferPosition.toFixed(4));
@@ -212,8 +206,7 @@ var LibraryOpenAL = {
err: 0,
src: [],
buf: [],
- interval: setInterval(function() { AL.updateSources(context); }, AL.QUEUE_INTERVAL),
- startTime: window['performance']['now']()
+ interval: setInterval(function() { AL.updateSources(context); }, AL.QUEUE_INTERVAL)
};
AL.contexts.push(context);
return AL.contexts.length;
diff --git a/src/parseTools.js b/src/parseTools.js
index 66354dca..90c5acab 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -35,8 +35,13 @@ function preprocess(text) {
var op = parts[2];
var value = parts[3];
if (op) {
- assert(op === '==')
- showStack.push(ident in this && this[ident] == value);
+ if (op === '==') {
+ showStack.push(ident in this && this[ident] == value);
+ } else if (op === '!=') {
+ showStack.push(!(ident in this && this[ident] == value));
+ } else {
+ error('unsupported preprecessor op ' + op);
+ }
} else {
showStack.push(ident in this && this[ident] > 0);
}
diff --git a/tests/gl_vertex_buffer.c b/tests/gl_vertex_buffer.c
new file mode 100644
index 00000000..6b695462
--- /dev/null
+++ b/tests/gl_vertex_buffer.c
@@ -0,0 +1,195 @@
+/*******************************************************************
+ * *
+ * 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 0
+#endif
+
+#if USE_GLEW
+#include "GL/glew.h"
+#endif
+
+#include <SDL/SDL.h>
+
+#if !USE_GLEW
+#include "SDL/SDL_opengl.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+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_MODELVIEW );
+ glLoadIdentity();
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ typedef struct Color {
+ GLubyte r;
+ GLubyte g;
+ GLubyte b;
+ GLubyte a;
+ } Color;
+
+ typedef struct Vertex {
+ GLfloat x;
+ GLfloat y;
+ Color color;
+ } Vertex;
+
+ Vertex vertices[18] = {
+ {-1.00, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-1.00, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.75, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.75, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ {-0.50, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.50, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.25, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-0.25, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.00, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.00, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 0.25, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.25, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.50, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ { 0.50, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.75, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.75, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 1.00, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 1.00, 1.0, {0xFF, 0xFF, 0x00, 0xFF}}
+ };
+
+ Vertex vertices2[18] = {
+ {-1.00, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-1.00, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.75, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.75, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ {-0.50, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.50, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.25, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-0.25, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.00, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.00, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 0.25, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.25, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.50, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ { 0.50, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.75, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.75, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 1.00, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 1.00, 0.0, {0xFF, 0xFF, 0x00, 0xFF}}
+ };
+
+ // make a vertex buffer for the second set of vertices
+ GLuint vbo = 0;
+ glGenBuffers(1, &vbo);
+
+
+ // bind to it
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ // send it to gl
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_READ); // GL_STATIC_READ is not in WebGL!
+
+ // unbind from it
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+ // DRAW
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ // This test ensures that we can use two separate arrays in memory for different
+ // attributes, and that they each can have different stride.
+ // The first test shows implicit striding (the zero indicates tightly packed)
+ // The second test shows explicit striding where the stride is passed in
+ // even though it also is tightly packed
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ // TEST 1 - clientside data
+
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex), vertices);
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &vertices[0].color);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
+ glDrawArrays(GL_TRIANGLE_STRIP, 10, 3);
+
+
+
+ // TEST 2 - bind to array buffer, gl*Pointer calls are offsets into the buffer, which was previously uploaded to
+
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex), 0);
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (GLvoid*)((GLvoid*)&vertices2[0].color - (GLvoid*)&vertices2[0]));
+
+// gldrawarrays first with a low number of vertices, then with a high number
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
+ glDrawArrays(GL_TRIANGLE_STRIP, 10, 3);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableClientState(GL_COLOR_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
+
+ SDL_Quit();
+
+ return 0;
+}
diff --git a/tests/gl_vertex_buffer.png b/tests/gl_vertex_buffer.png
new file mode 100644
index 00000000..3e1f2230
--- /dev/null
+++ b/tests/gl_vertex_buffer.png
Binary files differ
diff --git a/tests/gl_vertex_buffer_pre.c b/tests/gl_vertex_buffer_pre.c
new file mode 100644
index 00000000..84b76569
--- /dev/null
+++ b/tests/gl_vertex_buffer_pre.c
@@ -0,0 +1,177 @@
+/*******************************************************************
+ * *
+ * 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 0
+#endif
+
+#if USE_GLEW
+#include "GL/glew.h"
+#endif
+
+#include <SDL/SDL.h>
+
+#if !USE_GLEW
+#include "SDL/SDL_opengl.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+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_MODELVIEW );
+ glLoadIdentity();
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ typedef struct Color {
+ GLubyte r;
+ GLubyte g;
+ GLubyte b;
+ GLubyte a;
+ } Color;
+
+ typedef struct Vertex {
+ GLfloat x;
+ GLfloat y;
+ Color color;
+ } Vertex;
+
+ Vertex vertices[18] = {
+ {-1.00, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-1.00, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.75, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.75, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ {-0.50, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.50, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.25, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-0.25, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.00, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.00, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 0.25, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.25, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.50, 0.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ { 0.50, 1.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.75, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.75, 1.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 1.00, 0.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 1.00, 1.0, {0xFF, 0xFF, 0x00, 0xFF}}
+ };
+
+ Vertex vertices2[18] = {
+ {-1.00, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-1.00, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.75, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.75, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ {-0.50, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.50, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.25, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ {-0.25, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ {-0.00, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ {-0.00, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 0.25, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.25, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.50, -1.0, {0xFF, 0x00, 0xFF, 0xFF}},
+ { 0.50, 0.0, {0xFF, 0xFF, 0x00, 0xFF}},
+ { 0.75, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 0.75, 0.0, {0xFF, 0xFF, 0xFF, 0xFF}},
+ { 1.00, -1.0, {0xFF, 0x00, 0x00, 0xFF}},
+ { 1.00, 0.0, {0xFF, 0xFF, 0x00, 0xFF}}
+ };
+
+ // make a vertex buffer for the second set of vertices
+ GLuint vbo = 0;
+ glGenBuffers(1, &vbo);
+
+
+ // bind to it
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ // send it to gl
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
+
+ // unbind from it
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+ // DRAW
+
+ // Clear the screen before drawing
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ // This test ensures that we can use two separate arrays in memory for different
+ // attributes, and that they each can have different stride.
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex), vertices);
+ glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &vertices[0].color);
+ glDrawArrays(GL_TRIANGLE_STRIP, 10, 3);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableClientState(GL_COLOR_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
+
+ SDL_Quit();
+
+ return 0;
+}
diff --git a/tests/gl_vertex_buffer_pre.png b/tests/gl_vertex_buffer_pre.png
new file mode 100644
index 00000000..5677a868
--- /dev/null
+++ b/tests/gl_vertex_buffer_pre.png
Binary files differ
diff --git a/tests/test_browser.py b/tests/test_browser.py
index b014b4f6..3ac640f1 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -1207,6 +1207,12 @@ If manually bisecting:
def test_gl_stride(self):
self.btest('gl_stride.c', reference='gl_stride.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'])
+ def test_gl_vertex_buffer_pre(self):
+ self.btest('gl_vertex_buffer_pre.c', reference='gl_vertex_buffer_pre.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'])
+
+ def test_gl_vertex_buffer(self):
+ self.btest('gl_vertex_buffer.c', reference='gl_vertex_buffer.png', args=['-s', 'GL_UNSAFE_OPTS=0', '-s', 'LEGACY_GL_EMULATION=1'], reference_slack=1)
+
def test_matrix_identity(self):
self.btest('gl_matrix_identity.c', expected=['-1882984448', '460451840'], args=['-s', 'LEGACY_GL_EMULATION=1'])
diff --git a/tests/test_core.py b/tests/test_core.py
index 05d96914..2238859b 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -5751,8 +5751,8 @@ def process(filename):
if Settings.ASM_JS and os.path.exists(SPIDERMONKEY_ENGINE[0]):
out = run_js('liblib.so', engine=SPIDERMONKEY_ENGINE, full_output=True, stderr=STDOUT)
- assert 'asm' in out
- self.validate_asmjs(out)
+ if 'asm' in out:
+ self.validate_asmjs(out)
def test_dlfcn_data_and_fptr(self):
if Settings.ASM_JS: return self.skip('this is not a valid case - libraries should not be able to access their parents globals willy nilly')
@@ -6226,6 +6226,139 @@ ok
Settings.EXPORTED_FUNCTIONS = ['_main', '_malloc', '_free']
self.do_run(src, '''*294,153*''', force_c=True, post_build=self.dlfcn_post_build)
+ def test_dlfcn_longjmp(self):
+ if not self.can_dlfcn(): return
+
+ self.prep_dlfcn_lib()
+ lib_src = r'''
+ #include <setjmp.h>
+
+ void jumpy(jmp_buf buf) {
+ static int i = 0;
+ i++;
+ if (i == 10) longjmp(buf, i);
+ printf("pre %d\n", i);
+ }
+ '''
+ Settings.EXPORTED_FUNCTIONS = ['_jumpy']
+ dirname = self.get_dir()
+ filename = os.path.join(dirname, 'liblib.c')
+ self.build(lib_src, dirname, filename)
+ shutil.move(filename + '.o.js', os.path.join(dirname, 'liblib.so'))
+
+ self.prep_dlfcn_main()
+ src = r'''
+ #include <assert.h>
+ #include <stdio.h>
+ #include <dlfcn.h>
+ #include <setjmp.h&