diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-06-21 20:53:10 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-06-21 20:53:10 -0700 |
commit | 5b67262e1732d57379f484a61cdc1a7a9579b9ba (patch) | |
tree | 2c22b4525ffb2be24dc461476e65d9cd3bc6d889 | |
parent | 7e24c1344776fdeec1956372423c618f69a7e91b (diff) | |
parent | 6f3aafb70b9ef8053c899b0365d1f6cbab2887b6 (diff) |
Merge pull request #487 from ehsan/fog
Fog support for immediate mode
-rw-r--r-- | src/library_gl.js | 113 | ||||
-rwxr-xr-x | tests/runner.py | 28 | ||||
-rw-r--r-- | tests/screenshot-fog-density.png | bin | 0 -> 154012 bytes | |||
-rw-r--r-- | tests/screenshot-fog-exp2.png | bin | 0 -> 119847 bytes | |||
-rw-r--r-- | tests/screenshot-fog-linear.png | bin | 0 -> 247928 bytes | |||
-rw-r--r-- | tests/screenshot-fog-simple.png | bin | 0 -> 36557 bytes | |||
-rw-r--r-- | tests/sdl_fog_density.c | 183 | ||||
-rw-r--r-- | tests/sdl_fog_exp2.c | 184 | ||||
-rw-r--r-- | tests/sdl_fog_linear.c | 185 | ||||
-rw-r--r-- | tests/sdl_fog_simple.c | 182 |
10 files changed, 869 insertions, 6 deletions
diff --git a/src/library_gl.js b/src/library_gl.js index 08cb7511..89603572 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -909,7 +909,10 @@ var LibraryGL = { // Fog support. Partial, we assume shaders are used that implement fog. We just pass them uniforms fogStart: 0, fogEnd: 1, + fogDensity: 1.0, fogColor: null, + fogMode: 0x0800, // GL_EXP + fogEnabled: false, init: function() { GLEmulation.fogColor = new Float32Array(4); @@ -933,14 +936,32 @@ var LibraryGL = { // Clean up the renderer on any change to the rendering state. The optimization of // skipping renderer setup is aimed at the case of multiple glDraw* right after each other if (GL.immediate.lastRenderer) GL.immediate.lastRenderer.cleanup(); - if (!(cap in validCapabilities)) return; + if (cap == 0x0B60 /* GL_FOG */) { + GLEmulation.fogEnabled = true; + return; + } else if (!(cap in validCapabilities)) { + return; + } Module.ctx.enable(cap); }; _glDisable = function(cap) { if (GL.immediate.lastRenderer) GL.immediate.lastRenderer.cleanup(); - if (!(cap in validCapabilities)) return; + if (cap == 0x0B60 /* GL_FOG */) { + GLEmulation.fogEnabled = false; + return; + } else if (!(cap in validCapabilities)) { + return; + } Module.ctx.disable(cap); }; + _glIsEnabled = function(cap) { + if (cap == 0x0B60 /* GL_FOG */) { + return GLEmulation.fogEnabled ? 1 : 0; + } else if (!(cap in validCapabilities)) { + return 0; + } + return Module.ctx.isEnabled(cap); + }; var glGetIntegerv = _glGetIntegerv; _glGetIntegerv = function(pname, params) { @@ -1183,6 +1204,10 @@ var LibraryGL = { {{{ makeSetValue('params', '0', 'GLEmulation.fogStart', 'float') }}}; } else if (pname == 0x0B64) { // GL_FOG_END {{{ makeSetValue('params', '0', 'GLEmulation.fogEnd', 'float') }}}; + } else if (pname == 0x0B62) { // GL_FOG_DENSITY + {{{ makeSetValue('params', '0', 'GLEmulation.fogDensity', 'float') }}}; + } else if (pname == 0x0B65) { // GL_FOG_MODE + {{{ makeSetValue('params', '0', 'GLEmulation.fogMode', 'float') }}}; } else { glGetFloatv(pname, params); } @@ -1479,6 +1504,13 @@ var LibraryGL = { if (!cacheItem[GL.currProgram]) cacheItem[GL.currProgram] = {}; cacheItem = cacheItem[GL.currProgram]; } + if (GLEmulation.fogEnabled) { + var fogParam = GLEmulation.fogMode; + } else { + var fogParam = 0; // all valid modes are non-zero + } + if (!cacheItem[fogParam]) cacheItem[fogParam] = {}; + cacheItem = cacheItem[fogParam]; if (!cacheItem.renderer) { #if GL_DEBUG Module.printErr('generating renderer for ' + JSON.stringify(attributes)); @@ -1527,20 +1559,45 @@ var LibraryGL = { } this.program = GL.programs[GL.currProgram]; } else { + // IMPORTANT NOTE: If you parameterize the shader source based on any runtime values + // in order to create the least expensive shader possible based on the features being + // used, you should also update the code in the beginning of getRenderer to make sure + // that you cache the renderer based on the said parameters. this.vertexShader = Module.ctx.createShader(Module.ctx.VERTEX_SHADER); var zero = positionSize == 2 ? '0, ' : ''; + if (GLEmulation.fogEnabled) { + 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'; + break; + case 0x2601: // GL_LINEAR + // fog = (gl_Fog.end - gl_FogFragCoord) * gl_fog.scale + var fogFormula = ' float fog = (u_fogEnd - ecDistance) * u_fogScale; \n'; + 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'; + break; + } + } Module.ctx.shaderSource(this.vertexShader, 'attribute vec' + positionSize + ' a_position; \n' + 'attribute vec2 a_texCoord0; \n' + (hasTextures ? 'varying vec2 v_texCoord; \n' : '') + 'varying vec4 v_color; \n' + (colorSize ? 'attribute vec4 a_color; \n': 'uniform vec4 u_color; \n') + + (GLEmulation.fogEnabled ? 'varying float v_fogFragCoord; \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' + + ' vec4 ecPosition = (u_modelView * vec4(a_position, ' + zero + '1.0)); \n' + // eye-coordinate position + ' 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' : '') + '} \n'); Module.ctx.compileShader(this.vertexShader); @@ -1549,10 +1606,22 @@ var LibraryGL = { 'varying vec2 v_texCoord; \n' + 'uniform sampler2D u_texture; \n' + 'varying vec4 v_color; \n' + + (GLEmulation.fogEnabled ? ( + 'varying float v_fogFragCoord; \n' + + 'uniform vec4 u_fogColor; \n' + + 'uniform float u_fogEnd; \n' + + 'uniform float u_fogScale; \n' + + 'float ffog(in float ecDistance) { \n' + + fogFormula + + ' fog = clamp(fog, 0.0, 1.0); \n' + + ' return fog; \n' + + '} \n' + ) : '') + 'void main() \n' + '{ \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' : '') + '} \n'); Module.ctx.compileShader(this.fragmentShader); @@ -1997,7 +2066,7 @@ var LibraryGL = { }, glColor4us__deps: ['glColor4f'], glColor4us: function(r, g, b, a) { - _glColor4f((r&65525)/65535, (g&65525)/65535, (b&65525)/65535, (a&65525)/65535); + _glColor4f((r&65535)/65535, (g&65535)/65535, (b&65535)/65535, (a&65535)/65535); }, glColor4ui__deps: ['glColor4f'], glColor4ui: function(r, g, b, a) { @@ -2048,10 +2117,24 @@ var LibraryGL = { GLEmulation.fogStart = param; break; case 0x0B64: // GL_FOG_END GLEmulation.fogEnd = param; break; + case 0x0B62: // GL_FOG_DENSITY + GLEmulation.fogDensity = param; break; + case 0x0B65: // GL_FOG_MODE + switch (param) { + case 0x0801: // GL_EXP2 + case 0x2601: // GL_LINEAR + GLEmulation.fogMode = param; break; + default: // default to GL_EXP + GLEmulation.fogMode = 0x0800 /* GL_EXP */; break; + } + break; } }, - glFogi: function(){}, // TODO - glFogx: function(){}, // TODO + glFogi__deps: ['glFogf'], + glFogi: function(pname, param) { + return _glFogf(pname, param); + }, + glFogfv__deps: ['glFogf'], glFogfv: function(pname, param) { // partial support, TODO switch(pname) { case 0x0B66: // GL_FOG_COLOR @@ -2060,8 +2143,26 @@ var LibraryGL = { GLEmulation.fogColor[2] = {{{ makeGetValue('param', '8', 'float') }}}; GLEmulation.fogColor[3] = {{{ makeGetValue('param', '12', 'float') }}}; break; + case 0x0B63: // GL_FOG_START + case 0x0B64: // GL_FOG_END + _glFogf(pname, {{{ makeGetValue('param', '0', 'float') }}}); break; + } + }, + glFogiv__deps: ['glFogf'], + glFogiv: function(pname, param) { + switch(pname) { + case 0x0B66: // GL_FOG_COLOR + GLEmulation.fogColor[0] = ({{{ makeGetValue('param', '0', 'i32') }}}/2147483647)/2.0+0.5; + GLEmulation.fogColor[1] = ({{{ makeGetValue('param', '4', 'i32') }}}/2147483647)/2.0+0.5; + GLEmulation.fogColor[2] = ({{{ makeGetValue('param', '8', 'i32') }}}/2147483647)/2.0+0.5; + GLEmulation.fogColor[3] = ({{{ makeGetValue('param', '12', 'i32') }}}/2147483647)/2.0+0.5; + break; + default: + _glFogf(pname, {{{ makeGetValue('param', '0', 'i32') }}}); break; } }, + glFogx: 'glFogi', + glFogxv: 'glFogiv', glPolygonMode: function(){}, // TODO diff --git a/tests/runner.py b/tests/runner.py index 61520d53..c0f4e564 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -7652,6 +7652,34 @@ elif 'browser' in str(sys.argv): Popen(['python', EMCC, path_from_root('tests', 'sdl_ogl_p.c'), '-o', 'something.html', '--pre-js', 'reftest.js', '--preload-file', 'screenshot.png']).communicate() self.run_browser('something.html', 'You should see an image with gray at the top.', '/report_result?0') + def test_sdl_fog_simple(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-simple.png')) + 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_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')) + self.reftest(path_from_root('tests', 'screenshot-fog-density.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_density.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_exp2(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-exp2.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_exp2.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_linear(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-linear.png')) + Popen(['python', EMCC, path_from_root('tests', 'sdl_fog_linear.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_worker(self): # Test running in a web worker output = Popen(['python', EMCC, path_from_root('tests', 'hello_world_worker.cpp'), '-o', 'worker.js'], stdout=PIPE, stderr=PIPE).communicate() diff --git a/tests/screenshot-fog-density.png b/tests/screenshot-fog-density.png Binary files differnew file mode 100644 index 00000000..cd1f6f1b --- /dev/null +++ b/tests/screenshot-fog-density.png diff --git a/tests/screenshot-fog-exp2.png b/tests/screenshot-fog-exp2.png Binary files differnew file mode 100644 index 00000000..cd5e6a63 --- /dev/null +++ b/tests/screenshot-fog-exp2.png diff --git a/tests/screenshot-fog-linear.png b/tests/screenshot-fog-linear.png Binary files differnew file mode 100644 index 00000000..57534566 --- /dev/null +++ b/tests/screenshot-fog-linear.png diff --git a/tests/screenshot-fog-simple.png b/tests/screenshot-fog-simple.png Binary files differnew file mode 100644 index 00000000..527768fc --- /dev/null +++ b/tests/screenshot-fog-simple.png diff --git a/tests/sdl_fog_density.c b/tests/sdl_fog_density.c new file mode 100644 index 00000000..95773419 --- /dev/null +++ b/tests/sdl_fog_density.c @@ -0,0 +1,183 @@ +/******************************************************************* + * * + * 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); + glFogf(GL_FOG_DENSITY, 0.2); + + assert(glIsEnabled(GL_FOG)); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 10 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 10 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 10 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 10 ); + + 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; +} diff --git a/tests/sdl_fog_exp2.c b/tests/sdl_fog_exp2.c new file mode 100644 index 00000000..a09a5e3d --- /dev/null +++ b/tests/sdl_fog_exp2.c @@ -0,0 +1,184 @@ +/******************************************************************* + * * + * 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); + glFogf(GL_FOG_DENSITY, 0.2); + glFogi(GL_FOG_MODE, GL_EXP2); + + assert(glIsEnabled(GL_FOG)); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 10 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 10 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 10 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 10 ); + + 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; +} diff --git a/tests/sdl_fog_linear.c b/tests/sdl_fog_linear.c new file mode 100644 index 00000000..8fc18b7c --- /dev/null +++ b/tests/sdl_fog_linear.c @@ -0,0 +1,185 @@ +/******************************************************************* + * * + * 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); + glFogi(GL_FOG_START, 8); + glFogi(GL_FOG_END, 13); + glFogi(GL_FOG_MODE, GL_LINEAR); + + assert(glIsEnabled(GL_FOG)); + + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex3f( 10, 10, 10 ); + glTexCoord2i( 1, 0 ); glVertex3f( 300, 10, 10 ); + glTexCoord2i( 1, 1 ); glVertex3f( 300, 128, 10 ); + glTexCoord2i( 0, 1 ); glVertex3f( 10, 128, 10 ); + + 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; +} diff --git a/tests/sdl_fog_simple.c b/tests/sdl_fog_simple.c new file mode 100644 index 00000000..be023593 --- /dev/null +++ b/tests/sdl_fog_simple.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 ( |