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