aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library_gl.js113
-rw-r--r--src/runtime.js2
-rw-r--r--src/settings.js10
-rw-r--r--tests/cubegeom.c50
-rwxr-xr-xtests/runner.py19
-rw-r--r--tests/sdlglshader.c153
-rw-r--r--tests/sdlglshader.pngbin0 -> 36299 bytes
7 files changed, 263 insertions, 84 deletions
diff --git a/src/library_gl.js b/src/library_gl.js
index ccdfcb1e..29e9687c 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -6,7 +6,7 @@
var LibraryGL = {
$GL: {
#if GL_DEBUG
- debug: false,
+ debug: true,
#endif
counter: 1,
@@ -920,7 +920,7 @@ var LibraryGL = {
// Do some automatic rewriting to work around GLSL differences. Note that this must be done in
// tandem with the rest of the program, by itself it cannot suffice.
// Note that we need to remember shader types for this rewriting, saving sources makes it easier to debug.
- GL.shaderTypes = {};
+ GL.shaderInfos = {};
#if GL_DEBUG
GL.shaderSources = {};
GL.shaderOriginalSources = {};
@@ -928,7 +928,10 @@ var LibraryGL = {
var glCreateShader = _glCreateShader;
_glCreateShader = function(shaderType) {
var id = glCreateShader(shaderType);
- GL.shaderTypes[id] = shaderType;
+ GL.shaderInfos[id] = {
+ type: shaderType,
+ ftransform: false
+ };
return id;
};
@@ -938,8 +941,9 @@ var LibraryGL = {
#if GL_DEBUG
GL.shaderOriginalSources[shader] = source;
#endif
- if (GL.shaderTypes[shader] == Module.ctx.VERTEX_SHADER) {
+ if (GL.shaderInfos[shader].type == Module.ctx.VERTEX_SHADER) {
// Replace ftransform() with explicit project/modelview transforms, and add position and matrix info.
+ var old = source;
source = 'attribute vec4 a_position; \n\
uniform mat4 u_modelView; \n\
uniform mat4 u_projection; \n' +
@@ -949,6 +953,9 @@ var LibraryGL = {
.replace(/gl_ProjectionMatrix/g, 'u_projection')
.replace(/gl_ModelViewProjectionMatrix/g, 'u_modelView * u_projection')
.replace(/gl_ModelViewMatrixTranspose\[2\]/g, 'vec3(u_modelView[0][0], u_modelView[1][0], u_modelView[2][0])'); // XXX extremely inefficient
+ if (old != source) {
+ GL.shaderInfos[shader].ftransform = true; // we will need to provide the fixed function stuff as attributes and uniforms
+ }
for (var i = 0; i <= 6; i++) {
// XXX To handle both regular texture mapping and cube mapping, we use vec4 for tex coordinates.
var old = source;
@@ -993,7 +1000,7 @@ var LibraryGL = {
Module.ctx.compileShader(GL.shaders[shader]);
if (!Module.ctx.getShaderParameter(GL.shaders[shader], Module.ctx.COMPILE_STATUS)) {
console.log('Failed to compile shader: ' + Module.ctx.getShaderInfoLog(GL.shaders[shader]));
- console.log('Type: ' + GL.shaderTypes[shader]);
+ console.log('Info: ' + JSON.stringify(GL.shaderInfos[shader]));
#if GL_DEBUG
console.log('Original source: ' + GL.shaderOriginalSources[shader]);
console.log('Source: ' + GL.shaderSources[shader]);
@@ -1004,27 +1011,28 @@ var LibraryGL = {
}
};
-#if GL_DEBUG
GL.programShaders = {};
var glAttachShader = _glAttachShader;
_glAttachShader = function(program, shader) {
- if (!GL.programShaders[program]) GL.programShaders[program] = {};
- GL.programShaders[program][shader] = 1;
+ if (!GL.programShaders[program]) GL.programShaders[program] = [];
+ GL.programShaders[program].push(shader);
glAttachShader(program, shader);
};
var glUseProgram = _glUseProgram;
_glUseProgram = function(program) {
+#if GL_DEBUG
if (GL.debug) {
console.log('[using program with shaders:]');
- for (var shader in GL.programShaders[program]) {
+ GL.programShaders[program].forEach(function(shader) {
console.log(' shader ' + shader + ', original source: ' + GL.shaderOriginalSources[shader]);
console.log(' Source: ' + GL.shaderSources[shader]);
- }
+ });
}
+#endif
+ GL.currProgram = program;
glUseProgram(program);
}
-#endif
var glGetFloatv = _glGetFloatv;
_glGetFloatv = function(pname, params) {
@@ -1199,7 +1207,11 @@ var LibraryGL = {
this.renderer = renderer;
if (this.renderers[renderer]) return this.renderers[renderer];
- // Create renderer
+ this.createRenderer(renderer);
+ return this.renderers[renderer];
+ },
+
+ createRenderer: function(renderer) {
var vertexSize = 0, positionSize = 0, positionOffset = 0, textureSize = 0, textureOffset = 0, which, size;
for (var i = 0; i < renderer.length; i+=2) {
var which = renderer[i];
@@ -1223,39 +1235,51 @@ var LibraryGL = {
assert(positionSize > 0);
// 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] = {
vertexSize: vertexSize,
hasTexture: textureSize > 0,
init: function() {
- 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' +
- (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' : '') +
- '} \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' +
- 'void main() \n' +
- '{ \n' +
- (textureSize ? 'gl_FragColor = texture2D( s_texture, v_texCoord );\n' :
- 'gl_FragColor = vec4(0.8, 0.1, 1.0, 1.0);') +
- '} \n');
- Module.ctx.compileShader(this.fragmentShader);
-
- this.program = Module.ctx.createProgram();
- Module.ctx.attachShader(this.program, this.vertexShader);
- Module.ctx.attachShader(this.program, this.fragmentShader);
- Module.ctx.linkProgram(this.program);
+ if (useCurrProgram) {
+ if (GL.shaderInfos[GL.programShaders[GL.currProgram][0]].type == Module.ctx.VERTEX_SHADER) {
+ this.vertexShader = GL.shaders[GL.programShaders[GL.currProgram][0]];
+ this.fragmentShader = GL.shaders[GL.programShaders[GL.currProgram][1]];
+ } else {
+ this.vertexShader = GL.shaders[GL.programShaders[GL.currProgram][1]];
+ this.fragmentShader = GL.shaders[GL.programShaders[GL.currProgram][0]];
+ }
+ this.program = GL.programs[GL.currProgram];
+ } else {
+ 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' +
+ (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' : '') +
+ '} \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' +
+ 'void main() \n' +
+ '{ \n' +
+ (textureSize ? 'gl_FragColor = texture2D( s_texture, v_texCoord );\n' :
+ 'gl_FragColor = vec4(0.8, 0.1, 1.0, 1.0);') +
+ '} \n');
+ Module.ctx.compileShader(this.fragmentShader);
+
+ this.program = Module.ctx.createProgram();
+ Module.ctx.attachShader(this.program, this.vertexShader);
+ Module.ctx.attachShader(this.program, this.fragmentShader);
+ Module.ctx.linkProgram(this.program);
+ }
this.positionLocation = Module.ctx.getAttribLocation(this.program, 'a_position');
this.texCoordLocation = Module.ctx.getAttribLocation(this.program, 'a_texCoord');
@@ -1287,8 +1311,6 @@ var LibraryGL = {
}
};
this.renderers[renderer].init();
-
- return this.renderers[renderer];
},
// Main functions
@@ -1400,7 +1422,7 @@ var LibraryGL = {
$GLImmediateSetup__deps: ['$GLImmediate', function() { return 'GL.immediate = GLImmediate; GL.immediate.matrix.lib = ' + read('gl-matrix.js') + '; GL.immediate.initMatrixLibrary();\n' }],
$GLImmediateSetup: {},
- glBegin__deps: ['$GL', '$GLImmediateSetup'],
+ glBegin__deps: ['$GLImmediateSetup'],
glBegin: function(mode) {
if (!GL.immediate.initted) GL.immediate.init();
GL.immediate.mode = mode;
@@ -1499,6 +1521,7 @@ var LibraryGL = {
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);
},
@@ -1549,7 +1572,7 @@ var LibraryGL = {
glLoadMatrixf: function(matrix) {
#if GL_DEBUG
- console.log('glLoadMatrixf receiving: ' + Array.prototype.slice.call(HEAPF32.subarray(matrix >> 2, (matrix >> 2) + 16));
+ 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') }}});
diff --git a/src/runtime.js b/src/runtime.js
index 1e36ece6..7768574b 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -316,7 +316,7 @@ var Runtime = {
},
#if RUNTIME_DEBUG
- debug: false, // Switch to true at runtime to enable logging at the right times
+ debug: true, // Switch to false at runtime to disable logging at the right times
printObjectMap: null,
printObjectCounter: 1,
diff --git a/src/settings.js b/src/settings.js
index f630e5c3..452472d9 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -102,11 +102,11 @@ var SAFE_HEAP_LOG = 0; // Log out all SAFE_HEAP operations
var LABEL_DEBUG = 0; // Print out labels and functions as we enter them
var EXCEPTION_DEBUG = 1; // Print out exceptions in emscriptened code
-var LIBRARY_DEBUG = 0; // Print out when we enter a library call (library*.js). You must also set
- // Runtime.debug at runtime for logging to happen, and can unset it when you
- // no longer want logging. A simple way to set it in C++ is
- // emscripten_run_script("Runtime.debug = 1;");
-var GL_DEBUG = 0; // Print out all calls into WebGL. As with LIBRARY_DEBUG, you must set a runtime
+var LIBRARY_DEBUG = 0; // Print out when we enter a library call (library*.js). You can also unset
+ // Runtime.debug at runtime for logging to cease, and can set it when you
+ // want it back. A simple way to set it in C++ is
+ // emscripten_run_script("Runtime.debug = ...;");
+var GL_DEBUG = 0; // Print out all calls into WebGL. As with LIBRARY_DEBUG, you can set a runtime
// option, in this case GL.debug.
var DISABLE_EXCEPTION_CATCHING = 0; // Disables generating code to actually catch exceptions. If the code you
diff --git a/tests/cubegeom.c b/tests/cubegeom.c
index d022ea89..b82a08af 100644
--- a/tests/cubegeom.c
+++ b/tests/cubegeom.c
@@ -12,10 +12,14 @@ RESULTING FROM THE USE, MODIFICATION, OR
REDISTRIBUTION OF THIS SOFTWARE.
*/
+#if !EMSCRIPTEN
#include "GL/glew.h"
+#endif
#include "SDL/SDL.h"
-#include "SDL/SDL_image.h"
+#if EMSCRIPTEN
+#include "SDL/SDL_opengl.h"
+#endif
#include <stdio.h>
#include <string.h>
@@ -30,7 +34,7 @@ int main(int argc, char *argv[])
}
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
- screen = SDL_SetVideoMode( 1024, 768, 24, SDL_OPENGL );
+ screen = SDL_SetVideoMode( 640, 480, 24, SDL_OPENGL );
if ( !screen ) {
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
@@ -39,35 +43,21 @@ int main(int argc, char *argv[])
glClearColor( 0, 0, 0, 0 );
glClear( GL_COLOR_BUFFER_BIT );
- // Load the OpenGL texture
+ // Create a texture
GLuint texture;
- SDL_Surface *surface;
-
- if ( (surface = IMG_Load("screenshot.png")) ) {
- if ( (surface->w & (surface->w - 1)) != 0 ) {
- printf("warning: width is not a power of 2\n");
- }
- if ( (surface->h & (surface->h - 1)) != 0 ) {
- printf("warning: height is not a power of 2\n");
- }
-
- glGenTextures( 1, &texture );
- glBindTexture( GL_TEXTURE_2D, texture );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
- }
- else {
- printf("SDL could not load image.bmp: %s\n", SDL_GetError());
- SDL_Quit();
- return 1;
- }
-
- if ( surface ) {
- SDL_FreeSurface( surface );
+ glGenTextures( 1, &texture );
+ glBindTexture( GL_TEXTURE_2D, texture );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ GLubyte textureData[16*16*4];
+ for (int x = 0; x < 16; x++) {
+ for (int y = 0; y < 16; y++) {
+ *((int*)&textureData[(x*16 + y) * 4]) = x*16 + ((y*16) << 8);
+ }
}
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, textureData );
// Create a second texture
@@ -85,7 +75,9 @@ int main(int argc, char *argv[])
// BEGIN
+#if !EMSCRIPTEN
glewInit();
+#endif
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -99,7 +91,7 @@ int main(int argc, char *argv[])
glRotated(0, 0, 1, 0);
glRotated(0,-1, 0, 0);
glRotated(0, 0, 0,-1);
- glTranslated(-512,-512,-527);
+ //glTranslated(-512,-512,-527); // XXX this should be uncommented, but if it is then nothing is shown
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
diff --git a/tests/runner.py b/tests/runner.py
index f45b85e0..0d6df070 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -355,7 +355,6 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv) and 'brows
js_engines = filter(lambda engine: engine not in self.banned_js_engines, js_engines)
if len(js_engines) == 0: return self.skip('No JS engine present to run this test with. Check %s and settings.py and the paths therein.' % EM_CONFIG)
for engine in js_engines:
- engine = filter(lambda arg: arg != '-n', engine) # SpiderMonkey issue 716255
js_output = self.run_generated_code(engine, filename + '.o.js', args)
if output_nicerizer is not None:
js_output = output_nicerizer(js_output)
@@ -7214,10 +7213,22 @@ elif 'browser' in str(sys.argv):
Popen(['python', EMCC, program, '-o', 'program.html', '--pre-js', 'reftest.js'] + args).communicate()
self.run_browser('program.html', '', '/report_result?0')
+ def btest(self, filename, expected=None, reference=None, args=[]): # TODO: use in all other tests
+ if not reference:
+ open(os.path.join(self.get_dir(), filename), 'w').write(self.with_report_result(open(path_from_root('tests', filename)).read()))
+ else:
+ expected = '0' # 0 pixels difference than reference
+ shutil.copyfile(path_from_root('tests', filename), os.path.join(self.get_dir(), filename))
+ self.reftest(path_from_root('tests', reference))
+ args += ['--pre-js', 'reftest.js']
+ Popen(['python', EMCC, os.path.join(self.get_dir(), filename), '-o', 'test.html'] + args).communicate()
+ self.run_browser('test.html', '.', '/report_result?' + expected)
+
def test_emscripten_api(self):
- open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'emscripten_api_browser.cpp')).read()))
- Popen(['python', EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'page.html']).communicate()
- self.run_browser('page.html', '', '/report_result?1')
+ self.btest('emscripten_api_browser.cpp', '1')
+
+ def test_sdlglshader(self):
+ self.btest('sdlglshader.c', reference='sdlglshader.png')
elif 'benchmark' in str(sys.argv):
# Benchmarks. Run them with argument |benchmark|. To run a specific test, do
diff --git a/tests/sdlglshader.c b/tests/sdlglshader.c
new file mode 100644
index 00000000..a096ef20
--- /dev/null
+++ b/tests/sdlglshader.c
@@ -0,0 +1,153 @@
+/*
+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.
+*/
+
+#include "SDL/SDL.h"
+#include "SDL/SDL_opengl.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+// GL_ARB_shading_language_100, GL_ARB_shader_objects, GL_ARB_fragment_shader, GL_ARB_vertex_shader
+PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObject_ = NULL;
+PFNGLDELETEOBJECTARBPROC glDeleteObject_ = NULL;
+PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObject_ = NULL;
+PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObject_ = NULL;
+PFNGLSHADERSOURCEARBPROC glShaderSource_ = NULL;
+PFNGLCOMPILESHADERARBPROC glCompileShader_ = NULL;
+PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameteriv_ = NULL;
+PFNGLATTACHOBJECTARBPROC glAttachObject_ = NULL;
+PFNGLGETINFOLOGARBPROC glGetInfoLog_ = NULL;
+PFNGLLINKPROGRAMARBPROC glLinkProgram_ = NULL;
+PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocation_ = NULL;
+PFNGLUNIFORM1FARBPROC glUniform1f_ = NULL;
+PFNGLUNIFORM2FARBPROC glUniform2f_ = NULL;
+PFNGLUNIFORM3FARBPROC glUniform3f_ = NULL;
+PFNGLUNIFORM4FARBPROC glUniform4f_ = NULL;
+PFNGLUNIFORM1FVARBPROC glUniform1fv_ = NULL;
+PFNGLUNIFORM2FVARBPROC glUniform2fv_ = NULL;
+PFNGLUNIFORM3FVARBPROC glUniform3fv_ = NULL;
+PFNGLUNIFORM4FVARBPROC glUniform4fv_ = NULL;
+PFNGLUNIFORM1IARBPROC glUniform1i_ = NULL;
+PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocation_ = NULL;
+PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniform_ = NULL;
+
+void initARB() {
+ glCreateProgramObject_ = (PFNGLCREATEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glCreateProgramObjectARB");
+ glDeleteObject_ = (PFNGLDELETEOBJECTARBPROC) SDL_GL_GetProcAddress("glDeleteObjectARB");
+ glUseProgramObject_ = (PFNGLUSEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glUseProgramObjectARB");
+ glCreateShaderObject_ = (PFNGLCREATESHADEROBJECTARBPROC) SDL_GL_GetProcAddress("glCreateShaderObjectARB");
+ glShaderSource_ = (PFNGLSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glShaderSourceARB");
+ glCompileShader_ = (PFNGLCOMPILESHADERARBPROC) SDL_GL_GetProcAddress("glCompileShaderARB");
+ glGetObjectParameteriv_ = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB");
+ glAttachObject_ = (PFNGLATTACHOBJECTARBPROC) SDL_GL_GetProcAddress("glAttachObjectARB");
+ glGetInfoLog_ = (PFNGLGETINFOLOGARBPROC) SDL_GL_GetProcAddress("glGetInfoLogARB");
+ glLinkProgram_ = (PFNGLLINKPROGRAMARBPROC) SDL_GL_GetProcAddress("glLinkProgramARB");
+ glGetUniformLocation_ = (PFNGLGETUNIFORMLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetUniformLocationARB");
+ glUniform1f_ = (PFNGLUNIFORM1FARBPROC) SDL_GL_GetProcAddress("glUniform1fARB");
+ glUniform2f_ = (PFNGLUNIFORM2FARBPROC) SDL_GL_GetProcAddress("glUniform2fARB");
+ glUniform3f_ = (PFNGLUNIFORM3FARBPROC) SDL_GL_GetProcAddress("glUniform3fARB");
+ glUniform4f_ = (PFNGLUNIFORM4FARBPROC) SDL_GL_GetProcAddress("glUniform4fARB");
+ glUniform1fv_ = (PFNGLUNIFORM1FVARBPROC) SDL_GL_GetProcAddress("glUniform1fvARB");
+ glUniform2fv_ = (PFNGLUNIFORM2FVARBPROC) SDL_GL_GetProcAddress("glUniform2fvARB");
+ glUniform3fv_ = (PFNGLUNIFORM3FVARBPROC) SDL_GL_GetProcAddress("glUniform3fvARB");
+ glUniform4fv_ = (PFNGLUNIFORM4FVARBPROC) SDL_GL_GetProcAddress("glUniform4fvARB");
+ glUniform1i_ = (PFNGLUNIFORM1IARBPROC) SDL_GL_GetProcAddress("glUniform1iARB");
+ glBindAttribLocation_ = (PFNGLBINDATTRIBLOCATIONARBPROC) SDL_GL_GetProcAddress("glBindAttribLocationARB");
+ glGetActiveUniform_ = (PFNGLGETACTIVEUNIFORMARBPROC) SDL_GL_GetProcAddress("glGetActiveUniformARB");
+}
+
+void setShaders() {
+ GLuint v, f, p;
+ GLint ok;
+
+ const char *vv = "void main() \n"
+ "{ \n"
+ " gl_Position = ftransform() + vec4(0.1, -0.25, 0, 0); \n"
+ "}";
+ const char *ff = "void main() \n"
+ "{ \n"
+ " gl_FragColor = vec4(gl_FragCoord.y/480.0, gl_FragCoord.x/640.0, 0.66, 1.0); \n"
+ "}";
+
+ v = glCreateShaderObject_(GL_VERTEX_SHADER);
+ f = glCreateShaderObject_(GL_FRAGMENT_SHADER);
+
+ glShaderSource_(v, 1, &vv,NULL);
+ glShaderSource_(f, 1, &ff,NULL);
+
+ glCompileShader_(v);
+ glGetObjectParameteriv_(v, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
+ assert(ok);
+
+ glCompileShader_(f);
+ glGetObjectParameteriv_(f, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
+ assert(ok);
+
+ p = glCreateProgramObject_();
+ glAttachObject_(p,f);
+ glAttachObject_(p,v);
+
+ glLinkProgram_(p);
+ glGetObjectParameteriv_(p, GL_OBJECT_LINK_STATUS_ARB, &ok);
+ assert(ok);
+
+ glUseProgramObject_(p);
+}
+
+int main(int argc, char *argv[])
+{
+ SDL_Surface *screen;
+
+ assert(SDL_Init(SDL_INIT_VIDEO) == 0);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL );
+ assert(screen);
+
+ glClearColor(0, 0, 0, 0);
+ glViewport(0, 0, 640, 480);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, 640, 480, 0, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ initARB();
+ setShaders();
+
+ glColor3f(0, 1, 1); // is overridden by the shader, useful for debugging native builds
+ glBegin( GL_TRIANGLES );
+ glTexCoord2i(0, 0); glVertex3f( 10, 10, 0);
+ glTexCoord2i(1, 0); glVertex3f( 300, 10, 0);
+ glTexCoord2i(1, 1); glVertex3f( 300, 328, 0);
+ glEnd();
+
+ glColor3f(1, 1, 0); // is overridden by the shader, useful for debugging native builds
+ glBegin( GL_TRIANGLES );
+ glTexCoord2f(0, 0.5); glVertex3f(410, 10, 0);
+ glTexCoord2f(1, 0.5); glVertex3f(600, 10, 0);
+ glTexCoord2f(1, 1 ); glVertex3f(630, 400, 0);
+ glEnd();
+
+ SDL_GL_SwapBuffers();
+
+#if !EMSCRIPTEN
+ SDL_Delay(3000);
+#endif
+
+ SDL_Quit();
+ return 0;
+}
+
diff --git a/tests/sdlglshader.png b/tests/sdlglshader.png
new file mode 100644
index 00000000..5e52a617
--- /dev/null
+++ b/tests/sdlglshader.png
Binary files differ