diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-04-23 17:30:21 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-04-23 17:30:21 -0700 |
commit | 7a066b458e26064aaf50ee026f96721d9b3bb099 (patch) | |
tree | d96cc3fccafcfad54ad57f227a7edc02cd3fb898 | |
parent | aa5932c2b83f3aaf53e5b12795a25703781898db (diff) |
finish current immediate+shader work, add sdlglshader test
-rw-r--r-- | src/library_gl.js | 92 | ||||
-rwxr-xr-x | tests/runner.py | 8 | ||||
-rw-r--r-- | tests/sdlglshader.c | 153 | ||||
-rw-r--r-- | tests/sdlglshader.png | bin | 0 -> 36299 bytes |
4 files changed, 202 insertions, 51 deletions
diff --git a/src/library_gl.js b/src/library_gl.js index dde424b0..23025466 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -1011,7 +1011,6 @@ var LibraryGL = { } }; -#if GL_DEBUG GL.programShaders = {}; var glAttachShader = _glAttachShader; _glAttachShader = function(program, shader) { @@ -1019,7 +1018,6 @@ var LibraryGL = { GL.programShaders[program].push(shader); glAttachShader(program, shader); }; -#endif var glUseProgram = _glUseProgram; _glUseProgram = function(program) { @@ -1206,30 +1204,14 @@ var LibraryGL = { }, setRenderer: function(renderer) { - if (GL.currProgram) { - // A user-defined program is in use, use that - renderer = 'U' + GL.currProgram; - } this.renderer = renderer; if (this.renderers[renderer]) return this.renderers[renderer]; - if (renderer[0] == 'U') { - this.createUserDefinedRenderer(renderer); - } else { - this.createAutomaticRenderer(renderer); - } - + this.createRenderer(renderer); return this.renderers[renderer]; }, - createAutomaticRenderer: function(renderer) { - this.renderers[renderer] = { - prepare: function() { - } - }; - }, - - createAutomaticRenderer: function(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]; @@ -1253,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'); diff --git a/tests/runner.py b/tests/runner.py index 1de6aa80..b0a3ddc8 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -7210,19 +7210,23 @@ 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, reference=None, args=[]): # TODO: use in all other tests + 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']).communicate() + 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): 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 # |benchmark.test_X|. 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 |