diff options
-rw-r--r-- | src/library_gl.js | 113 | ||||
-rw-r--r-- | src/runtime.js | 2 | ||||
-rw-r--r-- | src/settings.js | 10 | ||||
-rw-r--r-- | tests/cubegeom.c | 50 | ||||
-rwxr-xr-x | tests/runner.py | 19 | ||||
-rw-r--r-- | tests/sdlglshader.c | 153 | ||||
-rw-r--r-- | tests/sdlglshader.png | bin | 0 -> 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 Binary files differnew file mode 100644 index 00000000..5e52a617 --- /dev/null +++ b/tests/sdlglshader.png |