132001f49Smrg/* 232001f49Smrg * EXT_fog_coord. 332001f49Smrg * 432001f49Smrg * Based on glutskel.c by Brian Paul 532001f49Smrg * and NeHe's Volumetric fog tutorial! 632001f49Smrg * 732001f49Smrg * Daniel Borca 832001f49Smrg */ 932001f49Smrg 1032001f49Smrg#include <stdio.h> 1132001f49Smrg#include <stdlib.h> 1232001f49Smrg#include <math.h> 1332001f49Smrg#include <GL/glew.h> 1432001f49Smrg#include "glut_wrap.h" 1532001f49Smrg 1632001f49Smrg#define DEPTH 5.0f 1732001f49Smrg 1832001f49Smrgstatic GLfloat camz; 1932001f49Smrg 2032001f49Smrgstatic GLint fogMode; 2132001f49Smrgstatic GLboolean fogCoord; 2232001f49Smrgstatic GLfloat fogDensity = 0.75; 2332001f49Smrgstatic GLfloat fogStart = 1.0, fogEnd = DEPTH; 2432001f49Smrgstatic GLfloat fogColor[4] = {0.6f, 0.3f, 0.0f, 1.0f}; 2532001f49Smrgstatic const char *ModeStr = NULL; 2632001f49Smrgstatic GLboolean Arrays = GL_FALSE; 2732001f49Smrgstatic GLboolean Texture = GL_TRUE; 2832001f49Smrg 2932001f49Smrg 3032001f49Smrgstatic void 3132001f49SmrgReset(void) 3232001f49Smrg{ 3332001f49Smrg fogMode = 1; 3432001f49Smrg fogCoord = 1; 3532001f49Smrg fogDensity = 0.75; 3632001f49Smrg fogStart = 1.0; 3732001f49Smrg fogEnd = DEPTH; 3832001f49Smrg Arrays = GL_FALSE; 3932001f49Smrg Texture = GL_TRUE; 4032001f49Smrg} 4132001f49Smrg 4232001f49Smrg 4332001f49Smrgstatic void 4432001f49SmrgglFogCoordf_ext (GLfloat f) 4532001f49Smrg{ 4632001f49Smrg if (fogCoord) 4732001f49Smrg glFogCoordfEXT(f); 4832001f49Smrg} 4932001f49Smrg 5032001f49Smrg 5132001f49Smrgstatic void 5232001f49SmrgPrintString(const char *s) 5332001f49Smrg{ 5432001f49Smrg while (*s) { 5532001f49Smrg glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 5632001f49Smrg s++; 5732001f49Smrg } 5832001f49Smrg} 5932001f49Smrg 6032001f49Smrg 6132001f49Smrgstatic void 6232001f49SmrgPrintInfo(void) 6332001f49Smrg{ 6432001f49Smrg char s[100]; 6532001f49Smrg 6632001f49Smrg glDisable(GL_FOG); 6732001f49Smrg glColor3f(0, 1, 1); 6832001f49Smrg 6932001f49Smrg sprintf(s, "Mode(m): %s Start(s/S): %g End(e/E): %g Density(d/D): %g", 7032001f49Smrg ModeStr, fogStart, fogEnd, fogDensity); 7132001f49Smrg glWindowPos2iARB(5, 20); 7232001f49Smrg PrintString(s); 7332001f49Smrg 7432001f49Smrg sprintf(s, "Arrays(a): %s glFogCoord(c): %s EyeZ(z/z): %g", 7532001f49Smrg (Arrays ? "Yes" : "No"), 7632001f49Smrg (fogCoord ? "Yes" : "No"), 7732001f49Smrg camz); 7832001f49Smrg glWindowPos2iARB(5, 5); 7932001f49Smrg PrintString(s); 8032001f49Smrg} 8132001f49Smrg 8232001f49Smrg 8332001f49Smrgstatic int 8432001f49SmrgSetFogMode(GLint fogMode) 8532001f49Smrg{ 8632001f49Smrg fogMode &= 3; 8732001f49Smrg switch (fogMode) { 8832001f49Smrg case 0: 8932001f49Smrg ModeStr = "Off"; 9032001f49Smrg glDisable(GL_FOG); 9132001f49Smrg break; 9232001f49Smrg case 1: 9332001f49Smrg ModeStr = "GL_LINEAR"; 9432001f49Smrg glEnable(GL_FOG); 9532001f49Smrg glFogi(GL_FOG_MODE, GL_LINEAR); 9632001f49Smrg glFogf(GL_FOG_START, fogStart); 9732001f49Smrg glFogf(GL_FOG_END, fogEnd); 9832001f49Smrg break; 9932001f49Smrg case 2: 10032001f49Smrg ModeStr = "GL_EXP"; 10132001f49Smrg glEnable(GL_FOG); 10232001f49Smrg glFogi(GL_FOG_MODE, GL_EXP); 10332001f49Smrg glFogf(GL_FOG_DENSITY, fogDensity); 10432001f49Smrg break; 10532001f49Smrg case 3: 10632001f49Smrg ModeStr = "GL_EXP2"; 10732001f49Smrg glEnable(GL_FOG); 10832001f49Smrg glFogi(GL_FOG_MODE, GL_EXP2); 10932001f49Smrg glFogf(GL_FOG_DENSITY, fogDensity); 11032001f49Smrg break; 11132001f49Smrg } 11232001f49Smrg return fogMode; 11332001f49Smrg} 11432001f49Smrg 11532001f49Smrg 11632001f49Smrgstatic GLboolean 11732001f49SmrgSetFogCoord(GLboolean fogCoord) 11832001f49Smrg{ 11932001f49Smrg if (!GLEW_EXT_fog_coord) { 12032001f49Smrg return GL_FALSE; 12132001f49Smrg } 12232001f49Smrg 12332001f49Smrg if (fogCoord) { 12432001f49Smrg glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); 12532001f49Smrg } 12632001f49Smrg else { 12732001f49Smrg glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); 12832001f49Smrg } 12932001f49Smrg return fogCoord; 13032001f49Smrg} 13132001f49Smrg 13232001f49Smrg 13332001f49Smrg/* could reuse vertices */ 13432001f49Smrgstatic GLuint vertex_index[] = { 13532001f49Smrg /* Back */ 13632001f49Smrg 0, 1, 2, 3, 13732001f49Smrg 13832001f49Smrg /* Floor */ 13932001f49Smrg 4, 5, 6, 7, 14032001f49Smrg 14132001f49Smrg /* Roof */ 14232001f49Smrg 8, 9, 10, 11, 14332001f49Smrg 14432001f49Smrg /* Right */ 14532001f49Smrg 12, 13, 14, 15, 14632001f49Smrg 14732001f49Smrg /* Left */ 14832001f49Smrg 16, 17, 18, 19 14932001f49Smrg}; 15032001f49Smrg 15132001f49Smrgstatic GLfloat vertex_pointer[][3] = { 15232001f49Smrg /* Back */ 15332001f49Smrg {-1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, { 1.0f, 1.0f,-DEPTH}, {-1.0f, 1.0f,-DEPTH}, 15432001f49Smrg 15532001f49Smrg /* Floor */ 15632001f49Smrg {-1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f, 0.0}, {-1.0f,-1.0f, 0.0}, 15732001f49Smrg 15832001f49Smrg /* Roof */ 15932001f49Smrg {-1.0f, 1.0f,-DEPTH}, { 1.0f, 1.0f,-DEPTH}, { 1.0f, 1.0f, 0.0}, {-1.0f, 1.0f, 0.0}, 16032001f49Smrg 16132001f49Smrg /* Right */ 16232001f49Smrg { 1.0f,-1.0f, 0.0}, { 1.0f, 1.0f, 0.0}, { 1.0f, 1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, 16332001f49Smrg 16432001f49Smrg /* Left */ 16532001f49Smrg {-1.0f,-1.0f, 0.0}, {-1.0f, 1.0f, 0.0}, {-1.0f, 1.0f,-DEPTH}, {-1.0f,-1.0f,-DEPTH} 16632001f49Smrg}; 16732001f49Smrg 16832001f49Smrgstatic GLfloat texcoord_pointer[][2] = { 16932001f49Smrg /* Back */ 17032001f49Smrg {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}, 17132001f49Smrg 17232001f49Smrg /* Floor */ 17332001f49Smrg {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, DEPTH}, {0.0f, DEPTH}, 17432001f49Smrg 17532001f49Smrg /* Roof */ 17632001f49Smrg {1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, DEPTH}, {1.0f, DEPTH}, 17732001f49Smrg 17832001f49Smrg /* Right */ 17932001f49Smrg {0.0f, 1.0f}, {0.0f, 0.0f}, {DEPTH, 0.0f}, {DEPTH, 1.0f}, 18032001f49Smrg 18132001f49Smrg /* Left */ 18232001f49Smrg {0.0f, 0.0f}, {0.0f, 1.0f}, {DEPTH, 1.0f}, {DEPTH, 0.0f} 18332001f49Smrg}; 18432001f49Smrg 18532001f49Smrgstatic GLfloat fogcoord_pointer[] = { 18632001f49Smrg /* Back */ 18732001f49Smrg DEPTH, DEPTH, DEPTH, DEPTH, 18832001f49Smrg 18932001f49Smrg /* Floor */ 19032001f49Smrg DEPTH, DEPTH, 0.0, 0.0, 19132001f49Smrg 19232001f49Smrg /* Roof */ 19332001f49Smrg DEPTH, DEPTH, 0.0, 0.0, 19432001f49Smrg 19532001f49Smrg /* Right */ 19632001f49Smrg 0.0, 0.0, DEPTH, DEPTH, 19732001f49Smrg 19832001f49Smrg /* Left */ 19932001f49Smrg 0.0, 0.0, DEPTH, DEPTH 20032001f49Smrg}; 20132001f49Smrg 20232001f49Smrg 20332001f49Smrgstatic void 20432001f49SmrgDisplay( void ) 20532001f49Smrg{ 20632001f49Smrg glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 20732001f49Smrg glLoadIdentity (); 20832001f49Smrg 20932001f49Smrg glTranslatef(0.0f, 0.0f, -camz); 21032001f49Smrg 21132001f49Smrg SetFogMode(fogMode); 21232001f49Smrg 21332001f49Smrg glColor3f(1, 1, 1); 21432001f49Smrg 21532001f49Smrg if (Texture) 21632001f49Smrg glEnable(GL_TEXTURE_2D); 21732001f49Smrg 21832001f49Smrg if (Arrays) { 21932001f49Smrg glEnableClientState(GL_VERTEX_ARRAY); 22032001f49Smrg glEnableClientState(GL_TEXTURE_COORD_ARRAY); 22132001f49Smrg glDrawElements(GL_QUADS, sizeof(vertex_index) / sizeof(vertex_index[0]), 22232001f49Smrg GL_UNSIGNED_INT, vertex_index); 22332001f49Smrg glDisableClientState(GL_VERTEX_ARRAY); 22432001f49Smrg glDisableClientState(GL_TEXTURE_COORD_ARRAY); 22532001f49Smrg } 22632001f49Smrg else { 22732001f49Smrg /* Back */ 22832001f49Smrg glBegin(GL_QUADS); 22932001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH); 23032001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-DEPTH); 23132001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-DEPTH); 23232001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-DEPTH); 23332001f49Smrg glEnd(); 23432001f49Smrg 23532001f49Smrg /* Floor */ 23632001f49Smrg glBegin(GL_QUADS); 23732001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH); 23832001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-DEPTH); 23932001f49Smrg glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, DEPTH); glVertex3f( 1.0f,-1.0f,0.0); 24032001f49Smrg glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, DEPTH); glVertex3f(-1.0f,-1.0f,0.0); 24132001f49Smrg glEnd(); 24232001f49Smrg 24332001f49Smrg /* Roof */ 24432001f49Smrg glBegin(GL_QUADS); 24532001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f,-DEPTH); 24632001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-DEPTH); 24732001f49Smrg glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, DEPTH); glVertex3f( 1.0f, 1.0f,0.0); 24832001f49Smrg glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, DEPTH); glVertex3f(-1.0f, 1.0f,0.0); 24932001f49Smrg glEnd(); 25032001f49Smrg 25132001f49Smrg /* Right */ 25232001f49Smrg glBegin(GL_QUADS); 25332001f49Smrg glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,-1.0f,0.0); 25432001f49Smrg glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,0.0); 25532001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 0.0f); glVertex3f( 1.0f, 1.0f,-DEPTH); 25632001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 1.0f); glVertex3f( 1.0f,-1.0f,-DEPTH); 25732001f49Smrg glEnd(); 25832001f49Smrg 25932001f49Smrg /* Left */ 26032001f49Smrg glBegin(GL_QUADS); 26132001f49Smrg glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,0.0); 26232001f49Smrg glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,0.0); 26332001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 1.0f); glVertex3f(-1.0f, 1.0f,-DEPTH); 26432001f49Smrg glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH); 26532001f49Smrg glEnd(); 26632001f49Smrg } 26732001f49Smrg 26832001f49Smrg glDisable(GL_TEXTURE_2D); 26932001f49Smrg 27032001f49Smrg PrintInfo(); 27132001f49Smrg 27232001f49Smrg glutSwapBuffers(); 27332001f49Smrg} 27432001f49Smrg 27532001f49Smrg 27632001f49Smrgstatic void 27732001f49SmrgReshape( int width, int height ) 27832001f49Smrg{ 27932001f49Smrg glViewport(0, 0, width, height); 28032001f49Smrg glMatrixMode(GL_PROJECTION); 28132001f49Smrg glLoadIdentity(); 28232001f49Smrg glFrustum(-1, 1, -1, 1, 1.0, 100); 28332001f49Smrg glMatrixMode(GL_MODELVIEW); 28432001f49Smrg glLoadIdentity(); 28532001f49Smrg} 28632001f49Smrg 28732001f49Smrg 28832001f49Smrgstatic void 28932001f49SmrgKey( unsigned char key, int x, int y ) 29032001f49Smrg{ 29132001f49Smrg (void) x; 29232001f49Smrg (void) y; 29332001f49Smrg switch (key) { 29432001f49Smrg case 'a': 29532001f49Smrg Arrays = !Arrays; 29632001f49Smrg break; 29732001f49Smrg case 'f': 29832001f49Smrg case 'm': 29932001f49Smrg fogMode = SetFogMode(fogMode + 1); 30032001f49Smrg break; 30132001f49Smrg case 'D': 30232001f49Smrg fogDensity += 0.05; 30332001f49Smrg SetFogMode(fogMode); 30432001f49Smrg break; 30532001f49Smrg case 'd': 30632001f49Smrg if (fogDensity > 0.0) { 30732001f49Smrg fogDensity -= 0.05; 30832001f49Smrg } 30932001f49Smrg SetFogMode(fogMode); 31032001f49Smrg break; 31132001f49Smrg case 's': 31232001f49Smrg if (fogStart > 0.0) { 31332001f49Smrg fogStart -= 0.25; 31432001f49Smrg } 31532001f49Smrg SetFogMode(fogMode); 31632001f49Smrg break; 31732001f49Smrg case 'S': 31832001f49Smrg if (fogStart < 100.0) { 31932001f49Smrg fogStart += 0.25; 32032001f49Smrg } 32132001f49Smrg SetFogMode(fogMode); 32232001f49Smrg break; 32332001f49Smrg case 'e': 32432001f49Smrg if (fogEnd > 0.0) { 32532001f49Smrg fogEnd -= 0.25; 32632001f49Smrg } 32732001f49Smrg SetFogMode(fogMode); 32832001f49Smrg break; 32932001f49Smrg case 'E': 33032001f49Smrg if (fogEnd < 100.0) { 33132001f49Smrg fogEnd += 0.25; 33232001f49Smrg } 33332001f49Smrg SetFogMode(fogMode); 33432001f49Smrg break; 33532001f49Smrg case 'c': 33632001f49Smrg fogCoord = SetFogCoord(fogCoord ^ GL_TRUE); 33732001f49Smrg break; 33832001f49Smrg case 't': 33932001f49Smrg Texture = !Texture; 34032001f49Smrg break; 34132001f49Smrg case 'z': 34232001f49Smrg camz -= 0.1; 34332001f49Smrg break; 34432001f49Smrg case 'Z': 34532001f49Smrg camz += 0.1; 34632001f49Smrg break; 34732001f49Smrg case 'r': 34832001f49Smrg Reset(); 34932001f49Smrg break; 35032001f49Smrg case 27: 35132001f49Smrg exit(0); 35232001f49Smrg break; 35332001f49Smrg } 35432001f49Smrg glutPostRedisplay(); 35532001f49Smrg} 35632001f49Smrg 35732001f49Smrg 35832001f49Smrgstatic void 35932001f49SmrgInit(void) 36032001f49Smrg{ 36132001f49Smrg static const GLubyte teximage[2][2][4] = { 36232001f49Smrg { { 255, 255, 255, 255}, { 128, 128, 128, 255} }, 36332001f49Smrg { { 128, 128, 128, 255}, { 255, 255, 255, 255} } 36432001f49Smrg }; 36532001f49Smrg 36632001f49Smrg printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 36732001f49Smrg 36832001f49Smrg if (!GLEW_EXT_fog_coord) { 36932001f49Smrg printf("GL_EXT_fog_coord not supported!\n"); 37032001f49Smrg } 37132001f49Smrg 37232001f49Smrg glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, 37332001f49Smrg GL_RGBA, GL_UNSIGNED_BYTE, teximage); 37432001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 37532001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 37632001f49Smrg 37732001f49Smrg glClearColor(0.1f, 0.1f, 0.1f, 0.0f); 37832001f49Smrg 37932001f49Smrg glDepthFunc(GL_LEQUAL); 38032001f49Smrg glEnable(GL_DEPTH_TEST); 38132001f49Smrg glShadeModel(GL_SMOOTH); 38232001f49Smrg glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 38332001f49Smrg 38432001f49Smrg glFogfv(GL_FOG_COLOR, fogColor); 38532001f49Smrg glHint(GL_FOG_HINT, GL_NICEST); 38632001f49Smrg fogCoord = SetFogCoord(GL_TRUE); /* try to enable fog_coord */ 38732001f49Smrg fogMode = SetFogMode(1); 38832001f49Smrg 38932001f49Smrg glEnableClientState(GL_VERTEX_ARRAY); 39032001f49Smrg glVertexPointer(3, GL_FLOAT, 0, vertex_pointer); 39132001f49Smrg 39232001f49Smrg glEnableClientState(GL_TEXTURE_COORD_ARRAY); 39332001f49Smrg glTexCoordPointer(2, GL_FLOAT, 0, texcoord_pointer); 39432001f49Smrg 39532001f49Smrg if (GLEW_EXT_fog_coord) { 39632001f49Smrg glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT); 39732001f49Smrg glFogCoordPointerEXT(GL_FLOAT, 0, fogcoord_pointer); 39832001f49Smrg } 39932001f49Smrg 40032001f49Smrg Reset(); 40132001f49Smrg} 40232001f49Smrg 40332001f49Smrg 40432001f49Smrgint 40532001f49Smrgmain( int argc, char *argv[] ) 40632001f49Smrg{ 40732001f49Smrg glutInitWindowSize( 600, 600 ); 40832001f49Smrg glutInit( &argc, argv ); 40932001f49Smrg glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 41032001f49Smrg glutCreateWindow(argv[0]); 41132001f49Smrg glewInit(); 41232001f49Smrg glutReshapeFunc( Reshape ); 41332001f49Smrg glutKeyboardFunc( Key ); 41432001f49Smrg glutDisplayFunc( Display ); 41532001f49Smrg Init(); 41632001f49Smrg glutMainLoop(); 41732001f49Smrg return 0; 41832001f49Smrg} 419