aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc6
-rwxr-xr-xemscripten.py2
-rw-r--r--src/library_gl.js213
-rw-r--r--src/library_sdl.js4
-rw-r--r--system/include/libc/sys/types.h8
-rw-r--r--tests/cubegeom.c12
-rw-r--r--tests/gl_ps.c217
-rw-r--r--tests/gl_ps.pngbin0 -> 203535 bytes
-rwxr-xr-xtests/runner.py7
-rw-r--r--tests/sdl_ogl_p.c8
-rw-r--r--tools/shared.py18
11 files changed, 396 insertions, 99 deletions
diff --git a/emcc b/emcc
index a54b805b..2874741a 100755
--- a/emcc
+++ b/emcc
@@ -722,9 +722,9 @@ try:
# dlmalloc
def create_dlmalloc():
if DEBUG: print >> sys.stderr, 'emcc: building dlmalloc for cache'
- execute(['python', shared.EMCC, shared.path_from_root('system', 'lib', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')], stdout=stdout, stderr=stderr)
+ execute(shared.ENV_PREFIX + ['python', shared.EMCC, shared.path_from_root('system', 'lib', 'dlmalloc.c'), '-g', '-o', in_temp('dlmalloc.o')], stdout=stdout, stderr=stderr)
# we include the libc++ new stuff here, so that the common case of using just new/delete is quick to link
- execute(['python', shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', 'new.cpp'), '-g', '-o', in_temp('new.o')], stdout=stdout, stderr=stderr)
+ execute(shared.ENV_PREFIX + ['python', shared.EMXX, shared.path_from_root('system', 'lib', 'libcxx', 'new.cpp'), '-g', '-o', in_temp('new.o')], stdout=stdout, stderr=stderr)
shared.Building.link([in_temp('dlmalloc.o'), in_temp('new.o')], in_temp('dlmalloc_full.o'))
return in_temp('dlmalloc_full.o')
def fix_dlmalloc():
@@ -846,7 +846,7 @@ try:
if AUTODEBUG:
if DEBUG: print >> sys.stderr, 'emcc: autodebug'
- execute(['python', shared.AUTODEBUGGER, final, final + '.ad.ll'])
+ execute(shared.ENV_PREFIX + ['python', shared.AUTODEBUGGER, final, final + '.ad.ll'])
final += '.ad.ll'
if DEBUG: save_intermediate('autodebug', 'll')
diff --git a/emscripten.py b/emscripten.py
index 45c9f418..044d6cd9 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
'''
You should normally never use this! Use emcc instead.
diff --git a/src/library_gl.js b/src/library_gl.js
index 29e9687c..d3011c69 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -967,9 +967,13 @@ var LibraryGL = {
}
}
if (source.indexOf('gl_Color') >= 0) {
- source = 'attribute vec4 a_color; \n\
- varying vec4 v_color; \n' +
- source.replace(/gl_Color/g, 'a_color').replace(/gl_FrontColor/g, 'v_color');
+ source = 'varying vec4 v_color; \n' +
+ source.replace(/gl_Color/g, 'vec4(1, 1, 1, 1)').replace(/gl_FrontColor/g, 'v_color'); // XXX gl_Color can be either an attribute, or
+ // from glColor, and we don't know which here.
+ // For now, just use white
+ //source = 'attribute vec4 a_color; \n\
+ // varying vec4 v_color; \n' +
+ // source.replace(/gl_Color/g, 'a_color').replace(/gl_FrontColor/g, 'v_color');
}
if (source.indexOf('gl_FogFragCoord') >= 0) {
source = 'varying float v_fogCoord; \n' +
@@ -1034,6 +1038,32 @@ var LibraryGL = {
glUseProgram(program);
}
+ var glDeleteProgram = _glDeleteProgram;
+ _glDeleteProgram = function(program) {
+ glDeleteProgram(program);
+ if (program == GL.currProgram) GL.currProgram = 0;
+ };
+
+ var glBindBuffer = _glBindBuffer;
+ _glBindBuffer = function(target, buffer) {
+ glBindBuffer(target, buffer);
+ if (target == Module.ctx.ARRAY_BUFFER) {
+ GL.currArrayBuffer = buffer;
+ } else if (target == Module.ctx.ELEMENT_ARRAY_BUFFER) {
+ GL.currElementArrayBuffer = buffer;
+ }
+ };
+
+ var glDeleteBuffers = _glDeleteBuffers;
+ _glDeleteBuffers = function(n, buffers) {
+ glDeleteBuffers(n, buffers);
+ for (var i = 0; i < n; i++) {
+ var buffer = {{{ makeGetValue('buffers', 'i*4', 'i32') }}};
+ if (buffer == GL.currArrayBuffer) GL.currArrayBuffer = 0;
+ if (buffer == GL.currElementArrayBuffer) GL.currElementArrayBuffer = 0;
+ }
+ };
+
var glGetFloatv = _glGetFloatv;
_glGetFloatv = function(pname, params) {
if (pname == 0x0BA6) { // GL_MODELVIEW_MATRIX
@@ -1204,11 +1234,14 @@ var LibraryGL = {
},
setRenderer: function(renderer) {
- this.renderer = renderer;
- if (this.renderers[renderer]) return this.renderers[renderer];
-
- this.createRenderer(renderer);
- return this.renderers[renderer];
+ var name = renderer;
+ if (GL.currProgram && renderer[0] != 'U') {
+ name = 'UD' + GL.currProgram + '|' + renderer; // user-defined program renderer
+ }
+ this.renderer = name;
+ if (this.renderers[name]) return this.renderers[name];
+ this.renderers[name] = this.createRenderer(renderer);
+ return this.renderers[name];
},
createRenderer: function(renderer) {
@@ -1228,7 +1261,7 @@ var LibraryGL = {
textureOffset = vertexSize;
}
} else {
- throw 'Cannot create shader rendederer for ' + renderer + ' because of ' + which;
+ console.log('Warning: Ignoring renderer attribute ' + which);
}
vertexSize += size * 4; // XXX assuming float
}
@@ -1236,7 +1269,7 @@ var LibraryGL = {
// TODO: verify vertexSize is equal to the stride in enabled client arrays
// XXX TODO: use bufferSubData to prevent reallocation of new buffers? Or all on GPU and doesn't matter? Anyhow, use DYNAMIC as hint
var useCurrProgram = !!GL.currProgram;
- this.renderers[renderer] = {
+ var ret = {
vertexSize: vertexSize,
hasTexture: textureSize > 0,
init: function() {
@@ -1253,24 +1286,24 @@ var LibraryGL = {
this.vertexShader = Module.ctx.createShader(Module.ctx.VERTEX_SHADER);
var zero = positionSize == 2 ? '0, ' : '';
Module.ctx.shaderSource(this.vertexShader, 'attribute vec' + positionSize + ' a_position; \n' +
- 'attribute vec2 a_texCoord; \n' +
+ 'attribute vec2 a_texCoord0; \n' +
(textureSize ? 'varying vec2 v_texCoord; \n' : '') +
'uniform mat4 u_modelView; \n' +
'uniform mat4 u_projection; \n' +
'void main() \n' +
'{ \n' +
' gl_Position = u_projection * (u_modelView * vec4(a_position, ' + zero + '1.0)); \n' +
- (textureSize ? 'v_texCoord = a_texCoord; \n' : '') +
+ (textureSize ? 'v_texCoord = a_texCoord0; \n' : '') +
'} \n');
Module.ctx.compileShader(this.vertexShader);
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 s_texture; \n' +
+ 'uniform sampler2D u_texture; \n' +
'void main() \n' +
'{ \n' +
- (textureSize ? 'gl_FragColor = texture2D( s_texture, v_texCoord );\n' :
+ (textureSize ? 'gl_FragColor = texture2D( u_texture, v_texCoord );\n' :
'gl_FragColor = vec4(0.8, 0.1, 1.0, 1.0);') +
'} \n');
Module.ctx.compileShader(this.fragmentShader);
@@ -1282,8 +1315,8 @@ var LibraryGL = {
}
this.positionLocation = Module.ctx.getAttribLocation(this.program, 'a_position');
- this.texCoordLocation = Module.ctx.getAttribLocation(this.program, 'a_texCoord');
- this.textureLocation = Module.ctx.getUniformLocation(this.program, 's_texture');
+ this.texCoordLocation = Module.ctx.getAttribLocation(this.program, 'a_texCoord0');
+ this.textureLocation = Module.ctx.getUniformLocation(this.program, 'u_texture');
this.modelViewLocation = Module.ctx.getUniformLocation(this.program, 'u_modelView');
this.projectionLocation = Module.ctx.getUniformLocation(this.program, 'u_projection');
},
@@ -1301,16 +1334,19 @@ var LibraryGL = {
}
Module.ctx.enableVertexAttribArray(this.positionLocation);
- 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 (!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);
+ }
Module.ctx.uniformMatrix4fv(this.modelViewLocation, false, GL.immediate.matrix['m']);
Module.ctx.uniformMatrix4fv(this.projectionLocation, false, GL.immediate.matrix['p']);
}
};
- this.renderers[renderer].init();
+ ret.init();
+ return ret;
},
// Main functions
@@ -1332,43 +1368,62 @@ var LibraryGL = {
Module.ctx.drawArrays(mode, first, count);
return;
}
-#if ASSERTIONS
assert(first == 0); // TODO
-#endif
- // Client attributes are to be used here, emulate that
- var stride = 0, bytes = 0, attributes = [], start, renderer = '';
- for (var i = 0; i < GL.immediate.NUM_ATTRIBUTES; i++) {
- if (GL.immediate.enabledClientAttributes[i]) attributes.push(GL.immediate.clientAttributes[i]);
+
+ var renderer = GL.immediate.prepareClientAttributes(count);
+ GL.immediate.mode = mode;
+ GL.immediate.setRenderer(renderer);
+ GL.immediate.flush();
+ };
+
+ _glDrawElements = function(mode, count, type, indices) {
+ if (GL.immediate.totalEnabledClientAttributes == 0) {
+ Module.ctx.drawElements(mode, count, type, indices);
+ return;
}
- attributes.sort(function(x, y) { return !x ? (!y ? 0 : 1) : (!y ? -1 : (x.pointer - y.pointer)) });
- start = attributes[0].pointer;
- for (var i = 0; i < attributes.length; i++) {
- var attribute = attributes[i];
- if (!attribute) break;
+
+ var renderer = GL.immediate.prepareClientAttributes(count);
+ GL.immediate.mode = mode;
+ GL.immediate.setRenderer(renderer);
+ GL.immediate.flush(count);
+ };
+ },
+
+ prepareClientAttributes: function(count) {
+ // Client attributes are to be used here, emulate that
+ var stride = 0, bytes = 0, attributes = [], start, renderer = '';
+ for (var i = 0; i < GL.immediate.NUM_ATTRIBUTES; i++) {
+ if (GL.immediate.enabledClientAttributes[i]) attributes.push(GL.immediate.clientAttributes[i]);
+ }
+ attributes.sort(function(x, y) { return !x ? (!y ? 0 : 1) : (!y ? -1 : (x.pointer - y.pointer)) });
+ start = attributes[0].pointer;
+ for (var i = 0; i < attributes.length; i++) {
+ var attribute = attributes[i];
+ if (!attribute) break;
#if ASSERTIONS
- assert(attribute.stride);
- assert(stride == 0 || stride == attribute.stride); // must all be in the same buffer
+ assert(attribute.stride);
+ assert(stride == 0 || stride == attribute.stride); // must all be in the same buffer
#endif
- stride = attribute.stride;
- bytes += attribute.size * 4 * count; // XXX assuming float
- renderer += attribute.name;
- }
- for (var i = 0; i < attributes.length; i++) {
- var attribute = attributes[i];
- if (!attribute) break;
- attribute.offset = attribute.pointer - start;
+ stride = attribute.stride;
+ bytes += attribute.size * 4 * count; // XXX assuming float
+ renderer += attribute.name;
+ }
+ for (var i = 0; i < attributes.length; i++) {
+ var attribute = attributes[i];
+ if (!attribute) break;
+ attribute.offset = attribute.pointer - start;
#if ASSERTIONS
- assert(0 <= attribute.offset && attribute.offset < stride); // must all be in the same buffer
+ assert(0 <= attribute.offset && attribute.offset < stride); // must all be in the same buffer
#endif
- }
- GL.immediate.vertexData = {{{ makeHEAPView('F32', 'start', 'start + bytes') }}}; // XXX assuming float
- GL.immediate.vertexCounter = bytes / 4; // XXX assuming float
- GL.immediate.mode = mode;
- GL.immediate.setRenderer(renderer);
- GL.immediate.flush();
- };
+ }
+
+ GL.immediate.vertexData = {{{ makeHEAPView('F32', 'start', 'start + bytes') }}}; // XXX assuming float
+ GL.immediate.vertexCounter = bytes / 4; // XXX assuming float
+
+ return renderer;
},
- flush: function() {
+
+ flush: function(numProvidedIndexes) {
var renderer = this.setRenderer(this.renderer);
// Generate index data in a format suitable for GLES 2.0/WebGL
@@ -1377,7 +1432,9 @@ var LibraryGL = {
assert(numVertexes % 1 == 0);
var numIndexes = 0;
- if (GL.immediate.mode > 6) { // above GL_TRIANGLE_FAN are the non-GL ES modes
+ if (numProvidedIndexes) {
+ numIndexes = numProvidedIndexes;
+ } else if (GL.immediate.mode > 6) { // above GL_TRIANGLE_FAN are the non-GL ES modes
if (GL.immediate.mode == 7) { // GL_QUADS
var numQuads = numVertexes / 4;
assert(numQuads % 1 == 0);
@@ -1399,22 +1456,34 @@ var LibraryGL = {
Module.ctx.bufferData(Module.ctx.ELEMENT_ARRAY_BUFFER, this.indexData.subarray(0, numIndexes), Module.ctx.STATIC_DRAW);
}
- Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, this.vertexObject);
- Module.ctx.bufferData(Module.ctx.ARRAY_BUFFER, this.vertexData.subarray(0, this.vertexCounter), Module.ctx.STATIC_DRAW);
+ if (!GL.currArrayBuffer) {
+ Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, this.vertexObject);
+ Module.ctx.bufferData(Module.ctx.ARRAY_BUFFER, this.vertexData.subarray(0, this.vertexCounter), Module.ctx.STATIC_DRAW);
+ }
// Render
- Module.ctx.useProgram(renderer.program);
- Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, this.vertexObject);
+ if (!GL.currProgram) {
+ Module.ctx.useProgram(renderer.program);
+ }
renderer.prepare();
if (numIndexes) {
- Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, this.indexObject);
+ if (!numProvidedIndexes) {
+ Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, this.indexObject);
+ }
Module.ctx.drawElements(Module.ctx.TRIANGLES, numIndexes, Module.ctx.UNSIGNED_SHORT, 0);
} else {
Module.ctx.drawArrays(GL.immediate.mode, 0, numVertexes);
}
+ if (!GL.currArrayBuffer) {
+ Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, null);
+ }
+ if (!GL.currProgram) {
+ Module.ctx.useProgram(null);
+ }
+
this.vertexCounter = 0;
}
},
@@ -1518,22 +1587,22 @@ var LibraryGL = {
_glEnableClientState(cap, 1);
},
- glTexCoordPointer: function(size, type, stride, pointer) {
- GL.immediate.setClientAttribute('T' + GL.immediate.clientActiveTexture, size, type, stride, pointer);
- },
glVertexPointer__deps: ['$GLEmulation'], // if any pointers are used, glVertexPointer must be, and if it is, then we need emulation
glVertexPointer: function(size, type, stride, pointer) {
GL.immediate.setClientAttribute('V', size, type, stride, pointer);
},
- glNormalPointer: function(size, type, stride, pointer) {
- GL.immediate.setClientAttribute('N', size, type, stride, pointer);
+ glTexCoordPointer: function(size, type, stride, pointer) {
+ GL.immediate.setClientAttribute('T' + GL.immediate.clientActiveTexture, size, type, stride, pointer);
+ },
+ glNormalPointer: function(type, stride, pointer) {
+ GL.immediate.setClientAttribute('N', 1, type, stride, pointer);
},
glColorPointer: function(size, type, stride, pointer) {
GL.immediate.setClientAttribute('C', size, type, stride, pointer);
},
glClientActiveTexture: function(texture) {
- GL.immediate.clientActiveTexture = texture;
+ GL.immediate.clientActiveTexture = texture - 0x84C0; // GL_TEXTURE0
},
// OpenGL Immediate Mode matrix routines.
@@ -1566,27 +1635,23 @@ var LibraryGL = {
},
glLoadMatrixd: function(matrix) {
- GL.immediate.matrix.lib.mat4.set(GL.immediate.matrix[GL.immediate.currentMatrix],
- {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}});
+ GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]);
},
glLoadMatrixf: function(matrix) {
#if GL_DEBUG
console.log('glLoadMatrixf receiving: ' + Array.prototype.slice.call(HEAPF32.subarray(matrix >> 2, (matrix >> 2) + 16)));
#endif
- GL.immediate.matrix.lib.mat4.set(GL.immediate.matrix[GL.immediate.currentMatrix],
- {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}});
+ GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]);
},
glLoadTransposeMatrixd: function(matrix) {
- GL.immediate.matrix.lib.mat4.set(GL.immediate.matrix[GL.immediate.currentMatrix],
- {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}});
+ GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]);
GL.immediate.matrix.lib.mat4.transpose(GL.immediate.matrix[GL.immediate.currentMatrix]);
},
glLoadTransposeMatrixf: function(matrix) {
- GL.immediate.matrix.lib.mat4.set(GL.immediate.matrix[GL.immediate.currentMatrix],
- {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}});
+ GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}, GL.immediate.matrix[GL.immediate.currentMatrix]);
GL.immediate.matrix.lib.mat4.transpose(GL.immediate.matrix[GL.immediate.currentMatrix]);
},
@@ -1602,16 +1667,14 @@ var LibraryGL = {
glMultTransposeMatrixd: function(matrix) {
var colMajor = GL.immediate.matrix.lib.mat4.create();
- GL.immediate.matrix.lib.mat4.set(colMajor,
- {{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}});
+ GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F64', 'matrix', 'matrix+16*8') }}}, colMajor);
GL.immediate.matrix.lib.mat4.transpose(colMajor);
GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], colMajor);
},
glMultTransposeMatrixf: function(matrix) {
var colMajor = GL.immediate.matrix.lib.mat4.create();
- GL.immediate.matrix.lib.mat4.set(colMajor,
- {{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}});
+ GL.immediate.matrix.lib.mat4.set({{{ makeHEAPView('F32', 'matrix', 'matrix+16*4') }}}, colMajor);
GL.immediate.matrix.lib.mat4.transpose(colMajor);
GL.immediate.matrix.lib.mat4.multiply(GL.immediate.matrix[GL.immediate.currentMatrix], colMajor);
},
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 9e9bf10f..a4923352 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -774,6 +774,10 @@ var LibrarySDL = {
// SDL_Image
+ IMG_Init: function(flags) {
+ return flags; // We support JPG, PNG, TIF because browsers do
+ },
+
IMG_Load__deps: ['SDL_LockSurface'],
IMG_Load: function(filename) {
filename = FS.standardizePath(Pointer_stringify(filename));
diff --git a/system/include/libc/sys/types.h b/system/include/libc/sys/types.h
index 77acc92e..2f887537 100644
--- a/system/include/libc/sys/types.h
+++ b/system/include/libc/sys/types.h
@@ -140,12 +140,8 @@ typedef unsigned long vm_size_t;
#define __BIT_TYPES_DEFINED__
-// XXX Emscripten: removed unsigned types which are already defined
-typedef signed char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-typedef long long int64_t;
-typedef int32_t register_t;
+// XXX Emscripten: removed types which are already defined, get them from stdint
+#include <stdint.h>
#endif /* __MS_types__ */
/*
diff --git a/tests/cubegeom.c b/tests/cubegeom.c
index 1fb5eeef..529e1355 100644
--- a/tests/cubegeom.c
+++ b/tests/cubegeom.c
@@ -87,15 +87,15 @@ int main(int argc, char *argv[])
glLoadIdentity();
// original: glFrustum(-0.6435469817188064, 0.6435469817188064 ,-0.48266022190470925, 0.48266022190470925 ,0.5400000214576721, 2048);
glFrustum(-0.6435469817188064, 0.1435469817188064 ,-0.48266022190470925, 0.88266022190470925 ,0.5400000214576721, 2048);
+ //GLfloat pm[] = { 1.372136116027832, 0, 0, 0, 0, 0.7910231351852417, 0, 0, -0.6352481842041016, 0.29297152161598206, -1.0005275011062622, -1, 0, 0, -1.080284833908081, 0 };
+ //glLoadMatrixf(pm);
+
glMatrixMode(GL_MODELVIEW);
GLfloat matrixData[] = { -1, 0, 0, 0,
0, 0,-1, 0,
0, 1, 0, 0,
0, 0, 0, 1 };
glLoadMatrixf(matrixData);
- glRotated(0, 0, 1, 0);
- glRotated(0,-1, 0, 0);
- glRotated(0, 0, 0,-1);
//glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown
glEnable(GL_CULL_FACE);
@@ -186,7 +186,7 @@ int main(int argc, char *argv[])
// sauer vertex data is apparently 0-12: V3F, 12: N1B, 16-24: T2F, 24-28: T2S, 28-32: C4B
glVertexPointer(3, GL_FLOAT, 32, (void*)0); // all these apply to the ARRAY_BUFFER that is bound
glTexCoordPointer(2, GL_FLOAT, 32, (void*)16);
- glClientActiveTexture(GL_TEXTURE1);
+ glClientActiveTexture(GL_TEXTURE1); // XXX seems to be ignored in native build
glTexCoordPointer(2, GL_SHORT, 32, (void*)24);
glClientActiveTexture(GL_TEXTURE0); // likely not needed, it is a cleanup
glNormalPointer(GL_BYTE, 32, (void*)12);
@@ -204,8 +204,8 @@ int main(int argc, char *argv[])
"void main(void)\n"
"{\n"
" gl_Position = ftransform();\n"
- " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/100 + texgenscroll.xy;\n" // added /100 here
- " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100 * 3.051851e-05;\n"
+ " gl_TexCoord[0].xy = gl_MultiTexCoord0.xy/100.0 + texgenscroll.xy;\n" // added /100 here
+ " gl_TexCoord[1].xy = gl_MultiTexCoord1.xy/100.0 * 3.051851e-05;\n"
"}\n";
const char *fragmentShader = "uniform vec4 colorparams;\n"
"uniform sampler2D diffusemap, lightmap;\n"
diff --git a/tests/gl_ps.c b/tests/gl_ps.c
new file mode 100644
index 00000000..c4ec7675
--- /dev/null
+++ b/tests/gl_ps.c
@@ -0,0 +1,217 @@
+/*******************************************************************
+ * *
+ * 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
+ GLfloat vertexData[] = { 0, 0, 10, 10, // texture2, position2
+ 1, 0, 300, 10,
+ 1, 1, 300, 128,
+ 0, 1, 10, 128,
+ 0, 0.5, 410, 10,
+ 1, 0.5, 600, 10,
+ 1, 1, 630, 200,
+ 0.5, 1, 310, 250,
+ 0, 0, 100, 300,
+ 1, 0, 300, 300,
+ 1, 1, 300, 400,
+ 0, 1, 100, 400 };
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 4*4, &vertexData[0]);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 4*4, &vertexData[2]);
+
+ 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.png b/tests/gl_ps.png
new file mode 100644
index 00000000..185f7166
--- /dev/null
+++ b/tests/gl_ps.png
Binary files differ
diff --git a/tests/runner.py b/tests/runner.py
index 0e1b4716..1d4b827c 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -7224,8 +7224,13 @@ elif 'browser' in str(sys.argv):
def test_sdlglshader(self):
self.btest('sdlglshader.c', reference='sdlglshader.png')
+ def test_gl_ps(self):
+ # pointers and a shader
+ shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png'))
+ self.btest('gl_ps.c', reference='gl_ps.png', args=['--preload-file', 'screenshot.png', '-s', 'GL_DEBUG=1'])
+
def zzztest_cubegeom(self):
- self.btest('cubegeom.c', reference='sdlglshader.png')
+ self.btest('cubegeom.c', reference='sdlglshader.png', args=['-s', 'GL_DEBUG=1'])
elif 'benchmark' in str(sys.argv):
# Benchmarks. Run them with argument |benchmark|. To run a specific test, do
diff --git a/tests/sdl_ogl_p.c b/tests/sdl_ogl_p.c
index 3978f66c..949aaa44 100644
--- a/tests/sdl_ogl_p.c
+++ b/tests/sdl_ogl_p.c
@@ -58,10 +58,12 @@ int main(int argc, char *argv[])
glViewport( 0, 0, 640, 480 );
glMatrixMode( GL_PROJECTION );
- glLoadIdentity();
+ 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
- glOrtho( 0, 640, 480, 0, -1, 1 );
-
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
diff --git a/tools/shared.py b/tools/shared.py
index 5751ef60..010351ee 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -216,7 +216,17 @@ try:
except NameError:
pass
-WINDOWS = sys.platform.startswith ('win')
+WINDOWS = sys.platform.startswith('win')
+
+# If we have 'env', we should use that to find python, because |python| may fail while |env python| may work
+# (For example, if system python is 3.x while we need 2.x, and env gives 2.x if told to do so.)
+ENV_PREFIX = []
+if not WINDOWS:
+ try:
+ assert 'Python' in Popen(['env', 'python', '-V'], stdout=PIPE, stderr=STDOUT).communicate()[0]
+ ENV_PREFIX = ['env']
+ except:
+ pass
# Temp file utilities
@@ -600,13 +610,13 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
if output_filename is None:
output_filename = filename + '.o'
try_delete(output_filename)
- Popen(['python', EMCC, filename] + args + ['-o', output_filename], stdout=stdout, stderr=stderr, env=env).communicate()
+ Popen(ENV_PREFIX + ['python', EMCC, filename] + args + ['-o', output_filename], stdout=stdout, stderr=stderr, env=env).communicate()
assert os.path.exists(output_filename), 'emcc could not create output file'
@staticmethod
def emar(action, output_filename, filenames, stdout=None, stderr=None, env=None):
try_delete(output_filename)
- Popen(['python', EMAR, action, output_filename] + filenames, stdout=stdout, stderr=stderr, env=env).communicate()
+ Popen(ENV_PREFIX + ['python', EMAR, action, output_filename] + filenames, stdout=stdout, stderr=stderr, env=env).communicate()
if 'c' in action:
assert os.path.exists(output_filename), 'emar could not create output file'
@@ -617,7 +627,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
# Run Emscripten
settings = Settings.serialize()
- compiler_output = timeout_run(Popen(['python', EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling')
+ compiler_output = timeout_run(Popen(ENV_PREFIX + ['python', EMSCRIPTEN, filename + ('.o.ll' if append_ext else ''), '-o', filename + '.o.js'] + settings + extra_args, stdout=PIPE), None, 'Compiling')
#print compiler_output
# Detect compilation crashes and errors