aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-04-23 17:30:21 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-04-23 17:30:21 -0700
commit7a066b458e26064aaf50ee026f96721d9b3bb099 (patch)
treed96cc3fccafcfad54ad57f227a7edc02cd3fb898
parentaa5932c2b83f3aaf53e5b12795a25703781898db (diff)
finish current immediate+shader work, add sdlglshader test
-rw-r--r--src/library_gl.js92
-rwxr-xr-xtests/runner.py8
-rw-r--r--tests/sdlglshader.c153
-rw-r--r--tests/sdlglshader.pngbin0 -> 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
new file mode 100644
index 00000000..5e52a617
--- /dev/null
+++ b/tests/sdlglshader.png
Binary files differ