diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-06-24 12:22:14 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-06-24 12:22:14 -0700 |
commit | 0f825f760fe62e13ba550dc05650e981959df1e6 (patch) | |
tree | 6d24f6ec1dfdf2cdb90a553ea31977c49a7e99af | |
parent | d21efe08b3baad41ae1ffa3a313e6ce30c6df182 (diff) | |
parent | 8ffa4e1f6b8622ea8425bd299bcca315c55c187c (diff) |
Merge pull request #488 from ehsan/fog
Fix the fog if the distance is negative
-rw-r--r-- | src/library_gl.js | 20 | ||||
-rwxr-xr-x | tests/runner.py | 7 | ||||
-rw-r--r-- | tests/screenshot-fog-negative.png | bin | 0 -> 79537 bytes | |||
-rw-r--r-- | tests/sdl_fog_negative.c | 182 |
4 files changed, 202 insertions, 7 deletions
diff --git a/src/library_gl.js b/src/library_gl.js index 89603572..6a337d00 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -1111,6 +1111,10 @@ var LibraryGL = { source = 'uniform float u_fogScale; \n' + source.replace(/gl_Fog.scale/g, 'u_fogScale'); } + if (source.indexOf('gl_Fog.density') >= 0) { + source = 'uniform float u_fogDensity; \n' + + source.replace(/gl_Fog.density/g, 'u_fogDensity'); + } if (source.indexOf('gl_FogFragCoord') >= 0) { source = 'varying float v_fogFragCoord; \n' + source.replace(/gl_FogFragCoord/g, 'v_fogFragCoord'); @@ -1569,8 +1573,7 @@ var LibraryGL = { switch (GLEmulation.fogMode) { case 0x0801: // GL_EXP2 // fog = exp(-(gl_Fog.density * gl_FogFragCoord)^2) - var fogFormula = ' float density = float(' + GLEmulation.fogDensity + '); \n' + - ' float fog = exp(-density * density * ecDistance * ecDistance); \n'; + var fogFormula = ' float fog = exp(-u_fogDensity * u_fogDensity * ecDistance * ecDistance); \n'; break; case 0x2601: // GL_LINEAR // fog = (gl_Fog.end - gl_FogFragCoord) * gl_fog.scale @@ -1578,8 +1581,7 @@ var LibraryGL = { break; default: // default to GL_EXP // fog = exp(-gl_Fog.density * gl_FogFragCoord) - var fogFormula = ' float density = float(' + GLEmulation.fogDensity + '); \n' + - ' float fog = exp(-density * ecDistance); \n'; + var fogFormula = ' float fog = exp(-u_fogDensity * ecDistance); \n'; break; } } @@ -1597,7 +1599,7 @@ var LibraryGL = { ' gl_Position = u_projection * ecPosition; \n' + (hasTextures ? 'v_texCoord = a_texCoord0; \n' : '') + (colorSize ? 'v_color = a_color; \n' : 'v_color = u_color; \n') + - (GLEmulation.fogEnabled ? 'v_fogFragCoord = ecPosition.z;\n' : '') + + (GLEmulation.fogEnabled ? 'v_fogFragCoord = abs(ecPosition.z);\n' : '') + '} \n'); Module.ctx.compileShader(this.vertexShader); @@ -1611,6 +1613,7 @@ var LibraryGL = { 'uniform vec4 u_fogColor; \n' + 'uniform float u_fogEnd; \n' + 'uniform float u_fogScale; \n' + + 'uniform float u_fogDensity; \n' + 'float ffog(in float ecDistance) { \n' + fogFormula + ' fog = clamp(fog, 0.0, 1.0); \n' + @@ -1621,7 +1624,7 @@ var LibraryGL = { '{ \n' + (hasTextures ? 'gl_FragColor = v_color * texture2D( u_texture, v_texCoord );\n' : 'gl_FragColor = v_color;\n') + - (GLEmulation.fogEnabled ? 'gl_FragColor = vec4(mix(vec3(u_fogColor), vec3(gl_FragColor), ffog(v_fogFragCoord)), gl_FragColor.a); \n' : '') + + (GLEmulation.fogEnabled ? 'gl_FragColor = vec4(mix(u_fogColor.rgb, gl_FragColor.rgb, ffog(v_fogFragCoord)), gl_FragColor.a); \n' : '') + '} \n'); Module.ctx.compileShader(this.fragmentShader); @@ -1661,7 +1664,9 @@ var LibraryGL = { this.fogColorLocation = Module.ctx.getUniformLocation(this.program, 'u_fogColor'); this.fogEndLocation = Module.ctx.getUniformLocation(this.program, 'u_fogEnd'); this.fogScaleLocation = Module.ctx.getUniformLocation(this.program, 'u_fogScale'); - this.hasFog = !!(this.fogColorLocation || this.fogEndLocation || this.fogScaleLocation); + this.fogDensityLocation = Module.ctx.getUniformLocation(this.program, 'u_fogDensity'); + this.hasFog = !!(this.fogColorLocation || this.fogEndLocation || + this.fogScaleLocation || this.fogDensityLocation); }, prepare: function() { @@ -1748,6 +1753,7 @@ var LibraryGL = { if (this.fogColorLocation) Module.ctx.uniform4fv(this.fogColorLocation, GLEmulation.fogColor); if (this.fogEndLocation) Module.ctx.uniform1f(this.fogEndLocation, GLEmulation.fogEnd); if (this.fogScaleLocation) Module.ctx.uniform1f(this.fogScaleLocation, 1/(GLEmulation.fogEnd - GLEmulation.fogStart)); + if (this.fogDensityLocation) Module.ctx.uniform1f(this.fogDensityLocation, GLEmulation.fogDensity); } }, diff --git a/tests/runner.py b/tests/runner.py index 654b0a97..b1c969f3 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -7683,6 +7683,13 @@ elif 'browser' in str(sys.argv): Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_simple.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') + def test_sdl_fog_negative(self): + # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage + shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) + self.reftest(path_from_root('tests', 'screenshot-fog-negative.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_negative.c'), '-O2', '--minify', '0', '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() + self.run_browser('something.html', 'You should see an image with fog.', '/report_result?0') + def test_sdl_fog_density(self): # SDL, OpenGL, textures, fog, immediate mode. Closure for more coverage shutil.copyfile(path_from_root('tests', 'screenshot.png'), os.path.join(self.get_dir(), 'screenshot.png')) diff --git a/tests/screenshot-fog-negative.png b/tests/screenshot-fog-negative.png Binary files differnew file mode 100644 index 00000000..5b18a201 --- /dev/null +++ b/tests/screenshot-fog-negative.png diff --git a/tests/sdl_fog_negative.c b/tests/sdl_fog_negative.c new file mode 100644 index 00000000..2d589a47 --- /dev/null +++ b/tests/sdl_fog_negative.c @@ -0,0 +1,182 @@ +/******************************************************************* + * * + * 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. +*/ + +#include "SDL/SDL.h" +#include "SDL/SDL_image.h" +#include "SDL/SDL_opengl.h" + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +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 ); + glPushMatrix(); // just for testing + glLoadIdentity(); + + glOrtho( 0, 640, 480, 0, -1000, 1000 ); + + 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 ); + + // Bind the texture to which subsequent calls refer to + glBindTexture( GL_TEXTURE_2D, texture ); + + glEnable(GL_FOG); + GLfloat fogColor[] = { 1.0, 0.5, 0.5, 0.05 }; + glFogfv(GL_FOG_COLOR, fogColor); + + assert(glIsEnabled(GL_FOG)); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, -1 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, -1 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, -1 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, -1 ); + + glTexCoord2f( 0, 0.5 ); glVertex3f( 410, 10, -5 ); + glTexCoord2f( 1, 0.5 ); glVertex3f( 600, 10, -6 ); + glTexCoord2f( 1, 1 ); glVertex3f( 630, 200, -7 ); + glTexCoord2f( 0.5, 1 ); glVertex3f( 310, 250, -8 ); + glEnd(); + + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2i( 0, 0 ); glVertex3f( 100, 300, -1 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 300, -1 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 400, -1 ); + glTexCoord2i( 0, 1 ); glVertex3f( 500, 410, -1 ); + glEnd(); + +#if !EMSCRIPTEN + glDisable(GL_TEXTURE_2D); +#endif + + glColor3ub(90, 255, 255); + glBegin( GL_QUADS ); + glVertex3f( 10, 410, -5 ); + glVertex3f( 300, 410, -50 ); + glVertex3f( 300, 480, -100 ); + glVertex3f( 10, 470, -5 ); + glEnd(); + + glBegin( GL_QUADS ); + glColor3f(1.0, 0, 1.0); glVertex3f( 410, 410, -10 ); + glColor3f(0, 1.0, 0); glVertex3f( 600, 410, -10 ); + glColor3f(0, 0, 1.0); glVertex3f( 600, 480, -10 ); + glColor3f(1.0, 1.0, 1.0); glVertex3f( 410, 470, -10 ); + glEnd(); + + SDL_GL_SwapBuffers(); + +#if !EMSCRIPTEN + // Wait for 3 seconds to give us a chance to see the image + SDL_Delay(30000); +#endif + + // Now we can delete the OpenGL texture and close down SDL + glDeleteTextures( 1, &texture ); + + SDL_Quit(); + + return 0; +} |