diff options
Diffstat (limited to 'progs/demos')
| -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 0000000000..e44d1178c0 --- /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; +} | 
