diff options
Diffstat (limited to 'progs/demos/fogcoord.c')
-rw-r--r-- | progs/demos/fogcoord.c | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/progs/demos/fogcoord.c b/progs/demos/fogcoord.c new file mode 100644 index 00000000000..e44d1178c0c --- /dev/null +++ b/progs/demos/fogcoord.c @@ -0,0 +1,414 @@ +/* + * EXT_fog_coord. + * + * Based on glutskel.c by Brian Paul + * and NeHe's Volumetric fog tutorial! + * + * Daniel Borca + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> + +#include "readtex.c" /* the compulsory hack */ + +#define TEXTURE_FILE "../images/bw.rgb" + +#define ARRAYS 0 /* use glDrawElements */ + +#define VERBOSE 1 /* tell me what happens */ + +#define DEPTH 15.0f +#define EPS 1e-6f + +typedef void (GLAPIENTRYP GLFOGCOORDFEXTPROC) (GLfloat f); +typedef void (GLAPIENTRYP GLFOGCOORDPOINTEREXTPROC) (GLenum, GLsizei, const GLvoid *); + +static GLFOGCOORDFEXTPROC glFogCoordf_ext; +static GLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext; +static GLboolean have_fog_coord; + +static GLfloat camz; +static GLuint texture[1]; + +static GLint fogMode; +static GLboolean fogCoord; +static GLfloat fogDensity = 0.75; +static GLfloat fogStart = 0.0, fogEnd = 1.0; +static GLfloat fogColor[4] = {0.6f, 0.3f, 0.0f, 1.0f}; + + +void APIENTRY glFogCoordf_nop (GLfloat f) +{ + (void)f; +} + + +static int BuildTexture (const char *filename, GLuint texid[]) +{ + GLubyte *tex_data; + GLenum tex_format; + GLint tex_width, tex_height; + + tex_data = LoadRGBImage(filename, &tex_width, &tex_height, &tex_format); + if (tex_data == NULL) { + return -1; + } + + { + GLint tex_max; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &tex_max); + if ((tex_width > tex_max) || (tex_height > tex_max)) { + return -1; + } + } + + glGenTextures(1, texid); + + glBindTexture(GL_TEXTURE_2D, texid[0]); + 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, tex_format, tex_width, tex_height, 0, tex_format, GL_UNSIGNED_BYTE, tex_data); + + return 0; +} + + +static int SetFogMode (GLint fogMode) +{ + fogMode &= 3; + switch (fogMode) { + case 0: + glDisable(GL_FOG); +#if VERBOSE + printf("fog(disable)\n"); +#endif + break; + case 1: + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_LINEAR); + glFogf(GL_FOG_START, fogStart); + glFogf(GL_FOG_END, fogEnd); +#if VERBOSE + printf("fog(GL_LINEAR, %.2f, %.2f)\n", fogStart, fogEnd); +#endif + break; + case 2: + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP); + glFogf(GL_FOG_DENSITY, fogDensity); +#if VERBOSE + printf("fog(GL_EXP, %.2f)\n", fogDensity); +#endif + break; + case 3: + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP2); + glFogf(GL_FOG_DENSITY, fogDensity); +#if VERBOSE + printf("fog(GL_EXP2, %.2f)\n", fogDensity); +#endif + break; + } + return fogMode; +} + + +static GLboolean SetFogCoord (GLboolean fogCoord) +{ + glFogCoordf_ext = glFogCoordf_nop; + + if (!have_fog_coord) { +#if VERBOSE + printf("fog(GL_FRAGMENT_DEPTH_EXT)%s\n", fogCoord ? " EXT_fog_coord not available!" : ""); +#endif + return GL_FALSE; + } + + if (fogCoord) { + glFogCoordf_ext = (GLFOGCOORDFEXTPROC)glutGetProcAddress("glFogCoordfEXT"); + glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); +#if VERBOSE + printf("fog(GL_FOG_COORDINATE_EXT)\n"); +#endif + } else { + glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); +#if VERBOSE + printf("fog(GL_FRAGMENT_DEPTH_EXT)\n"); +#endif + } + return fogCoord; +} + + +#if ARRAYS +/* could reuse vertices */ +static GLuint vertex_index[] = { + /* Back */ + 0, 1, 2, 3, + + /* Floor */ + 4, 5, 6, 7, + + /* Roof */ + 8, 9, 10, 11, + + /* Right */ + 12, 13, 14, 15, + + /* Left */ + 16, 17, 18, 19 +}; + +static GLfloat vertex_pointer[][3] = { + /* Back */ + {-2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH}, { 2.5f, 2.5f,-DEPTH}, {-2.5f, 2.5f,-DEPTH}, + + /* Floor */ + {-2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f, DEPTH}, {-2.5f,-2.5f, DEPTH}, + + /* Roof */ + {-2.5f, 2.5f,-DEPTH}, { 2.5f, 2.5f,-DEPTH}, { 2.5f, 2.5f, DEPTH}, {-2.5f, 2.5f, DEPTH}, + + /* Right */ + { 2.5f,-2.5f, DEPTH}, { 2.5f, 2.5f, DEPTH}, { 2.5f, 2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH}, + + /* Left */ + {-2.5f,-2.5f, DEPTH}, {-2.5f, 2.5f, DEPTH}, {-2.5f, 2.5f,-DEPTH}, {-2.5f,-2.5f,-DEPTH} +}; + +static GLfloat texcoord_pointer[][2] = { + /* Back */ + {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}, + + /* Floor */ + {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}, + + /* Roof */ + {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}, + + /* Right */ + {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, + + /* Left */ + {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} +}; + +static GLfloat fogcoord_pointer[][1] = { + /* Back */ + {1.0f}, {1.0f}, {1.0f}, {1.0f}, + + /* Floor */ + {1.0f}, {1.0f}, {0.0f}, {0.0f}, + + /* Roof */ + {1.0f}, {1.0f}, {0.0f}, {0.0f}, + + /* Right */ + {0.0f}, {0.0f}, {1.0f}, {1.0f}, + + /* Left */ + {0.0f}, {0.0f}, {1.0f}, {1.0f} +}; +#endif + + +static void Display( void ) +{ + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity (); + + glTranslatef(0.0f, 0.0f, camz); + +#if ARRAYS + glDrawElements(GL_QUADS, sizeof(vertex_index) / sizeof(vertex_index[0]), GL_UNSIGNED_INT, vertex_index); +#else + /* Back */ + glBegin(GL_QUADS); + glFogCoordf_ext(1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.5f,-2.5f,-DEPTH); + glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.5f,-2.5f,-DEPTH); + glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.5f, 2.5f,-DEPTH); + glFogCoordf_ext(1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.5f, 2.5f,-DEPTH); + glEnd(); + + /* Floor */ + glBegin(GL_QUADS); + glFogCoordf_ext(1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.5f,-2.5f,-DEPTH); + glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.5f,-2.5f,-DEPTH); + glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.5f,-2.5f, DEPTH); + glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.5f,-2.5f, DEPTH); + glEnd(); + + /* Roof */ + glBegin(GL_QUADS); + glFogCoordf_ext(1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.5f, 2.5f,-DEPTH); + glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.5f, 2.5f,-DEPTH); + glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.5f, 2.5f, DEPTH); + glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.5f, 2.5f, DEPTH); + glEnd(); + + /* Right */ + glBegin(GL_QUADS); + glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 2.5f,-2.5f, DEPTH); + glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 2.5f, 2.5f, DEPTH); + glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.5f, 2.5f,-DEPTH); + glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.5f,-2.5f,-DEPTH); + glEnd(); + + /* Left */ + glBegin(GL_QUADS); + glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-2.5f,-2.5f, DEPTH); + glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-2.5f, 2.5f, DEPTH); + glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-2.5f, 2.5f,-DEPTH); + glFogCoordf_ext(1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-2.5f,-2.5f,-DEPTH); + glEnd(); +#endif + + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0f, (GLfloat)(width)/(GLfloat)(height), 0.1f, 100.0f); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 'f': + fogMode = SetFogMode(fogMode + 1); + break; + case '+': + if (fogDensity < 1.0 - EPS) { + fogDensity += 0.05; + } + SetFogMode(fogMode); + break; + case '-': + if (fogDensity > EPS) { + fogDensity -= 0.05; + } + SetFogMode(fogMode); + break; + case 's': + if (fogStart > EPS) { + fogStart -= 0.1; + } + SetFogMode(fogMode); + break; + case 'S': + if (fogStart < fogEnd - EPS) { + fogStart += 0.1; + } + SetFogMode(fogMode); + break; + case 'e': + if (fogEnd > fogStart + EPS) { + fogEnd -= 0.1; + } + SetFogMode(fogMode); + break; + case 'E': + if (fogEnd < 1.0 - EPS) { + fogEnd += 0.1; + } + SetFogMode(fogMode); + break; + case 'c': + fogCoord = SetFogCoord(fogCoord ^ GL_TRUE); + break; + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + if (camz < (DEPTH - 1.0)) { + camz += 1.0f; + } + break; + case GLUT_KEY_DOWN: + if (camz > -19.0) { + camz -= 1.0f; + } + break; + } + glutPostRedisplay(); +} + + +static void Init( void ) +{ + have_fog_coord = glutExtensionSupported("GL_EXT_fog_coord"); + + if (BuildTexture(TEXTURE_FILE, texture) == -1) { + exit(1); + } + + glEnable(GL_TEXTURE_2D); + glClearColor(0.0f, 0.0f, 0.0f, 0.5f); + glClearDepth(1.0f); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + glShadeModel(GL_SMOOTH); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + glFogfv(GL_FOG_COLOR, fogColor); + glHint(GL_FOG_HINT, GL_NICEST); + fogCoord = SetFogCoord(GL_TRUE); /* try to enable fog_coord */ + fogMode = SetFogMode(2); /* GL_EXP */ + + camz = -19.0f; + +#if ARRAYS + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertex_pointer); + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, texcoord_pointer); + + if (have_fog_coord) { + glFogCoordPointer_ext = (GLFOGCOORDPOINTEREXTPROC)glutGetProcAddress("glFogCoordPointerEXT"); + glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT); + glFogCoordPointer_ext(GL_FLOAT, 0, fogcoord_pointer); + } +#endif +} + + +int main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowPosition( 0, 0 ); + glutInitWindowSize( 640, 480 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); + glutCreateWindow(argv[0]); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + Init(); + glutMainLoop(); + return 0; +} |