1/* 2 * EXT_fog_coord. 3 * 4 * Based on glutskel.c by Brian Paul 5 * and NeHe's Volumetric fog tutorial! 6 * 7 * Daniel Borca 8 */ 9 10#include <stdio.h> 11#include <stdlib.h> 12#include <math.h> 13#include <GL/glew.h> 14#include "glut_wrap.h" 15 16#define DEPTH 5.0f 17 18static GLfloat camz; 19 20static GLint fogMode; 21static GLboolean fogCoord; 22static GLfloat fogDensity = 0.75; 23static GLfloat fogStart = 1.0, fogEnd = DEPTH; 24static GLfloat fogColor[4] = {0.6f, 0.3f, 0.0f, 1.0f}; 25static const char *ModeStr = NULL; 26static GLboolean Arrays = GL_FALSE; 27static GLboolean Texture = GL_TRUE; 28 29 30static void 31Reset(void) 32{ 33 fogMode = 1; 34 fogCoord = 1; 35 fogDensity = 0.75; 36 fogStart = 1.0; 37 fogEnd = DEPTH; 38 Arrays = GL_FALSE; 39 Texture = GL_TRUE; 40} 41 42 43static void 44glFogCoordf_ext (GLfloat f) 45{ 46 if (fogCoord) 47 glFogCoordfEXT(f); 48} 49 50 51static void 52PrintString(const char *s) 53{ 54 while (*s) { 55 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 56 s++; 57 } 58} 59 60 61static void 62PrintInfo(void) 63{ 64 char s[100]; 65 66 glDisable(GL_FOG); 67 glColor3f(0, 1, 1); 68 69 sprintf(s, "Mode(m): %s Start(s/S): %g End(e/E): %g Density(d/D): %g", 70 ModeStr, fogStart, fogEnd, fogDensity); 71 glWindowPos2iARB(5, 20); 72 PrintString(s); 73 74 sprintf(s, "Arrays(a): %s glFogCoord(c): %s EyeZ(z/z): %g", 75 (Arrays ? "Yes" : "No"), 76 (fogCoord ? "Yes" : "No"), 77 camz); 78 glWindowPos2iARB(5, 5); 79 PrintString(s); 80} 81 82 83static int 84SetFogMode(GLint fogMode) 85{ 86 fogMode &= 3; 87 switch (fogMode) { 88 case 0: 89 ModeStr = "Off"; 90 glDisable(GL_FOG); 91 break; 92 case 1: 93 ModeStr = "GL_LINEAR"; 94 glEnable(GL_FOG); 95 glFogi(GL_FOG_MODE, GL_LINEAR); 96 glFogf(GL_FOG_START, fogStart); 97 glFogf(GL_FOG_END, fogEnd); 98 break; 99 case 2: 100 ModeStr = "GL_EXP"; 101 glEnable(GL_FOG); 102 glFogi(GL_FOG_MODE, GL_EXP); 103 glFogf(GL_FOG_DENSITY, fogDensity); 104 break; 105 case 3: 106 ModeStr = "GL_EXP2"; 107 glEnable(GL_FOG); 108 glFogi(GL_FOG_MODE, GL_EXP2); 109 glFogf(GL_FOG_DENSITY, fogDensity); 110 break; 111 } 112 return fogMode; 113} 114 115 116static GLboolean 117SetFogCoord(GLboolean fogCoord) 118{ 119 if (!GLEW_EXT_fog_coord) { 120 return GL_FALSE; 121 } 122 123 if (fogCoord) { 124 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); 125 } 126 else { 127 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); 128 } 129 return fogCoord; 130} 131 132 133/* could reuse vertices */ 134static GLuint vertex_index[] = { 135 /* Back */ 136 0, 1, 2, 3, 137 138 /* Floor */ 139 4, 5, 6, 7, 140 141 /* Roof */ 142 8, 9, 10, 11, 143 144 /* Right */ 145 12, 13, 14, 15, 146 147 /* Left */ 148 16, 17, 18, 19 149}; 150 151static GLfloat vertex_pointer[][3] = { 152 /* Back */ 153 {-1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, { 1.0f, 1.0f,-DEPTH}, {-1.0f, 1.0f,-DEPTH}, 154 155 /* Floor */ 156 {-1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f, 0.0}, {-1.0f,-1.0f, 0.0}, 157 158 /* Roof */ 159 {-1.0f, 1.0f,-DEPTH}, { 1.0f, 1.0f,-DEPTH}, { 1.0f, 1.0f, 0.0}, {-1.0f, 1.0f, 0.0}, 160 161 /* Right */ 162 { 1.0f,-1.0f, 0.0}, { 1.0f, 1.0f, 0.0}, { 1.0f, 1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, 163 164 /* Left */ 165 {-1.0f,-1.0f, 0.0}, {-1.0f, 1.0f, 0.0}, {-1.0f, 1.0f,-DEPTH}, {-1.0f,-1.0f,-DEPTH} 166}; 167 168static GLfloat texcoord_pointer[][2] = { 169 /* Back */ 170 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}, 171 172 /* Floor */ 173 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, DEPTH}, {0.0f, DEPTH}, 174 175 /* Roof */ 176 {1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, DEPTH}, {1.0f, DEPTH}, 177 178 /* Right */ 179 {0.0f, 1.0f}, {0.0f, 0.0f}, {DEPTH, 0.0f}, {DEPTH, 1.0f}, 180 181 /* Left */ 182 {0.0f, 0.0f}, {0.0f, 1.0f}, {DEPTH, 1.0f}, {DEPTH, 0.0f} 183}; 184 185static GLfloat fogcoord_pointer[] = { 186 /* Back */ 187 DEPTH, DEPTH, DEPTH, DEPTH, 188 189 /* Floor */ 190 DEPTH, DEPTH, 0.0, 0.0, 191 192 /* Roof */ 193 DEPTH, DEPTH, 0.0, 0.0, 194 195 /* Right */ 196 0.0, 0.0, DEPTH, DEPTH, 197 198 /* Left */ 199 0.0, 0.0, DEPTH, DEPTH 200}; 201 202 203static void 204Display( void ) 205{ 206 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 207 glLoadIdentity (); 208 209 glTranslatef(0.0f, 0.0f, -camz); 210 211 SetFogMode(fogMode); 212 213 glColor3f(1, 1, 1); 214 215 if (Texture) 216 glEnable(GL_TEXTURE_2D); 217 218 if (Arrays) { 219 glEnableClientState(GL_VERTEX_ARRAY); 220 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 221 glDrawElements(GL_QUADS, sizeof(vertex_index) / sizeof(vertex_index[0]), 222 GL_UNSIGNED_INT, vertex_index); 223 glDisableClientState(GL_VERTEX_ARRAY); 224 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 225 } 226 else { 227 /* Back */ 228 glBegin(GL_QUADS); 229 glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH); 230 glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-DEPTH); 231 glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-DEPTH); 232 glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-DEPTH); 233 glEnd(); 234 235 /* Floor */ 236 glBegin(GL_QUADS); 237 glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH); 238 glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-DEPTH); 239 glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, DEPTH); glVertex3f( 1.0f,-1.0f,0.0); 240 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, DEPTH); glVertex3f(-1.0f,-1.0f,0.0); 241 glEnd(); 242 243 /* Roof */ 244 glBegin(GL_QUADS); 245 glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f,-DEPTH); 246 glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-DEPTH); 247 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, DEPTH); glVertex3f( 1.0f, 1.0f,0.0); 248 glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, DEPTH); glVertex3f(-1.0f, 1.0f,0.0); 249 glEnd(); 250 251 /* Right */ 252 glBegin(GL_QUADS); 253 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,-1.0f,0.0); 254 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,0.0); 255 glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 0.0f); glVertex3f( 1.0f, 1.0f,-DEPTH); 256 glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 1.0f); glVertex3f( 1.0f,-1.0f,-DEPTH); 257 glEnd(); 258 259 /* Left */ 260 glBegin(GL_QUADS); 261 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,0.0); 262 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,0.0); 263 glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 1.0f); glVertex3f(-1.0f, 1.0f,-DEPTH); 264 glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH); 265 glEnd(); 266 } 267 268 glDisable(GL_TEXTURE_2D); 269 270 PrintInfo(); 271 272 glutSwapBuffers(); 273} 274 275 276static void 277Reshape( int width, int height ) 278{ 279 glViewport(0, 0, width, height); 280 glMatrixMode(GL_PROJECTION); 281 glLoadIdentity(); 282 glFrustum(-1, 1, -1, 1, 1.0, 100); 283 glMatrixMode(GL_MODELVIEW); 284 glLoadIdentity(); 285} 286 287 288static void 289Key( unsigned char key, int x, int y ) 290{ 291 (void) x; 292 (void) y; 293 switch (key) { 294 case 'a': 295 Arrays = !Arrays; 296 break; 297 case 'f': 298 case 'm': 299 fogMode = SetFogMode(fogMode + 1); 300 break; 301 case 'D': 302 fogDensity += 0.05; 303 SetFogMode(fogMode); 304 break; 305 case 'd': 306 if (fogDensity > 0.0) { 307 fogDensity -= 0.05; 308 } 309 SetFogMode(fogMode); 310 break; 311 case 's': 312 if (fogStart > 0.0) { 313 fogStart -= 0.25; 314 } 315 SetFogMode(fogMode); 316 break; 317 case 'S': 318 if (fogStart < 100.0) { 319 fogStart += 0.25; 320 } 321 SetFogMode(fogMode); 322 break; 323 case 'e': 324 if (fogEnd > 0.0) { 325 fogEnd -= 0.25; 326 } 327 SetFogMode(fogMode); 328 break; 329 case 'E': 330 if (fogEnd < 100.0) { 331 fogEnd += 0.25; 332 } 333 SetFogMode(fogMode); 334 break; 335 case 'c': 336 fogCoord = SetFogCoord(fogCoord ^ GL_TRUE); 337 break; 338 case 't': 339 Texture = !Texture; 340 break; 341 case 'z': 342 camz -= 0.1; 343 break; 344 case 'Z': 345 camz += 0.1; 346 break; 347 case 'r': 348 Reset(); 349 break; 350 case 27: 351 exit(0); 352 break; 353 } 354 glutPostRedisplay(); 355} 356 357 358static void 359Init(void) 360{ 361 static const GLubyte teximage[2][2][4] = { 362 { { 255, 255, 255, 255}, { 128, 128, 128, 255} }, 363 { { 128, 128, 128, 255}, { 255, 255, 255, 255} } 364 }; 365 366 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 367 368 if (!GLEW_EXT_fog_coord) { 369 printf("GL_EXT_fog_coord not supported!\n"); 370 } 371 372 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, 373 GL_RGBA, GL_UNSIGNED_BYTE, teximage); 374 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 376 377 glClearColor(0.1f, 0.1f, 0.1f, 0.0f); 378 379 glDepthFunc(GL_LEQUAL); 380 glEnable(GL_DEPTH_TEST); 381 glShadeModel(GL_SMOOTH); 382 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 383 384 glFogfv(GL_FOG_COLOR, fogColor); 385 glHint(GL_FOG_HINT, GL_NICEST); 386 fogCoord = SetFogCoord(GL_TRUE); /* try to enable fog_coord */ 387 fogMode = SetFogMode(1); 388 389 glEnableClientState(GL_VERTEX_ARRAY); 390 glVertexPointer(3, GL_FLOAT, 0, vertex_pointer); 391 392 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 393 glTexCoordPointer(2, GL_FLOAT, 0, texcoord_pointer); 394 395 if (GLEW_EXT_fog_coord) { 396 glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT); 397 glFogCoordPointerEXT(GL_FLOAT, 0, fogcoord_pointer); 398 } 399 400 Reset(); 401} 402 403 404int 405main( int argc, char *argv[] ) 406{ 407 glutInitWindowSize( 600, 600 ); 408 glutInit( &argc, argv ); 409 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 410 glutCreateWindow(argv[0]); 411 glewInit(); 412 glutReshapeFunc( Reshape ); 413 glutKeyboardFunc( Key ); 414 glutDisplayFunc( Display ); 415 Init(); 416 glutMainLoop(); 417 return 0; 418} 419