4 * Based on glutskel.c by Brian Paul
5 * and NeHe's Volumetric fog tutorial!
18 #define TEXTURE_FILE "../images/bw.rgb"
20 #define ARRAYS 0 /* use glDrawElements */
22 #define VERBOSE 1 /* tell me what happens */
26 #if !defined(GLAPIENTRYP)
27 # define GLAPIENTRYP *
30 typedef void (GLAPIENTRYP GLFOGCOORDFEXTPROC
) (GLfloat f
);
31 typedef void (GLAPIENTRYP GLFOGCOORDPOINTEREXTPROC
) (GLenum
, GLsizei
, const GLvoid
*);
33 static GLFOGCOORDFEXTPROC glFogCoordf_ext
;
35 static GLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext
;
37 static GLboolean have_fog_coord
;
40 static GLuint texture
[1];
43 static GLboolean fogCoord
;
44 static GLfloat fogDensity
= 0.75;
45 static GLfloat fogStart
= 1.0, fogEnd
= 40.0;
46 static GLfloat fogColor
[4] = {0.6f
, 0.3f
, 0.0f
, 1.0f
};
49 static void APIENTRY
glFogCoordf_nop (GLfloat f
)
55 static int BuildTexture (const char *filename
, GLuint texid
[])
59 GLint tex_width
, tex_height
;
61 tex_data
= LoadRGBImage(filename
, &tex_width
, &tex_height
, &tex_format
);
62 if (tex_data
== NULL
) {
68 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &tex_max
);
69 if ((tex_width
> tex_max
) || (tex_height
> tex_max
)) {
74 glGenTextures(1, texid
);
76 glBindTexture(GL_TEXTURE_2D
, texid
[0]);
77 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
78 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
80 glTexImage2D(GL_TEXTURE_2D
, 0, tex_format
, tex_width
, tex_height
, 0,
81 tex_format
, GL_UNSIGNED_BYTE
, tex_data
);
87 static int SetFogMode (GLint fogMode
)
94 printf("fog(disable)\n");
99 glFogi(GL_FOG_MODE
, GL_LINEAR
);
100 glFogf(GL_FOG_START
, fogStart
);
101 glFogf(GL_FOG_END
, fogEnd
);
103 printf("fog(GL_LINEAR, %.2f, %.2f)\n", fogStart
, fogEnd
);
108 glFogi(GL_FOG_MODE
, GL_EXP
);
109 glFogf(GL_FOG_DENSITY
, fogDensity
);
111 printf("fog(GL_EXP, %.2f)\n", fogDensity
);
116 glFogi(GL_FOG_MODE
, GL_EXP2
);
117 glFogf(GL_FOG_DENSITY
, fogDensity
);
119 printf("fog(GL_EXP2, %.2f)\n", fogDensity
);
127 static GLboolean
SetFogCoord (GLboolean fogCoord
)
129 glFogCoordf_ext
= glFogCoordf_nop
;
131 if (!have_fog_coord
) {
133 printf("fog(GL_FRAGMENT_DEPTH_EXT)%s\n", fogCoord
? " EXT_fog_coord not available!" : "");
139 glFogCoordf_ext
= (GLFOGCOORDFEXTPROC
)glutGetProcAddress("glFogCoordfEXT");
140 glFogi(GL_FOG_COORDINATE_SOURCE_EXT
, GL_FOG_COORDINATE_EXT
);
142 printf("fog(GL_FOG_COORDINATE_EXT)\n");
145 glFogi(GL_FOG_COORDINATE_SOURCE_EXT
, GL_FRAGMENT_DEPTH_EXT
);
147 printf("fog(GL_FRAGMENT_DEPTH_EXT)\n");
155 /* could reuse vertices */
156 static GLuint vertex_index
[] = {
173 static GLfloat vertex_pointer
[][3] = {
175 {-2.5f
,-2.5f
,-DEPTH
}, { 2.5f
,-2.5f
,-DEPTH
}, { 2.5f
, 2.5f
,-DEPTH
}, {-2.5f
, 2.5f
,-DEPTH
},
178 {-2.5f
,-2.5f
,-DEPTH
}, { 2.5f
,-2.5f
,-DEPTH
}, { 2.5f
,-2.5f
, DEPTH
}, {-2.5f
,-2.5f
, DEPTH
},
181 {-2.5f
, 2.5f
,-DEPTH
}, { 2.5f
, 2.5f
,-DEPTH
}, { 2.5f
, 2.5f
, DEPTH
}, {-2.5f
, 2.5f
, DEPTH
},
184 { 2.5f
,-2.5f
, DEPTH
}, { 2.5f
, 2.5f
, DEPTH
}, { 2.5f
, 2.5f
,-DEPTH
}, { 2.5f
,-2.5f
,-DEPTH
},
187 {-2.5f
,-2.5f
, DEPTH
}, {-2.5f
, 2.5f
, DEPTH
}, {-2.5f
, 2.5f
,-DEPTH
}, {-2.5f
,-2.5f
,-DEPTH
}
190 static GLfloat texcoord_pointer
[][2] = {
192 {0.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 1.0f
},
195 {0.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 1.0f
},
198 {0.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 1.0f
},
201 {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
},
204 {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
}
207 static GLfloat fogcoord_pointer
[][1] = {
209 {1.0f
}, {1.0f
}, {1.0f
}, {1.0f
},
212 {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
},
215 {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
},
218 {0.0f
}, {0.0f
}, {1.0f
}, {1.0f
},
221 {0.0f
}, {0.0f
}, {1.0f
}, {1.0f
}
226 static void Display( void )
228 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
231 glTranslatef(0.0f
, 0.0f
, camz
);
234 glDrawElements(GL_QUADS
, sizeof(vertex_index
) / sizeof(vertex_index
[0]), GL_UNSIGNED_INT
, vertex_index
);
238 glFogCoordf_ext(1.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f(-2.5f
,-2.5f
,-DEPTH
);
239 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f( 2.5f
,-2.5f
,-DEPTH
);
240 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f( 2.5f
, 2.5f
,-DEPTH
);
241 glFogCoordf_ext(1.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f(-2.5f
, 2.5f
,-DEPTH
);
246 glFogCoordf_ext(1.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f(-2.5f
,-2.5f
,-DEPTH
);
247 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f( 2.5f
,-2.5f
,-DEPTH
);
248 glFogCoordf_ext(0.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f( 2.5f
,-2.5f
, DEPTH
);
249 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f(-2.5f
,-2.5f
, DEPTH
);
254 glFogCoordf_ext(1.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f(-2.5f
, 2.5f
,-DEPTH
);
255 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f( 2.5f
, 2.5f
,-DEPTH
);
256 glFogCoordf_ext(0.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f( 2.5f
, 2.5f
, DEPTH
);
257 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f(-2.5f
, 2.5f
, DEPTH
);
262 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f( 2.5f
,-2.5f
, DEPTH
);
263 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f( 2.5f
, 2.5f
, DEPTH
);
264 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f( 2.5f
, 2.5f
,-DEPTH
);
265 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f( 2.5f
,-2.5f
,-DEPTH
);
270 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f(-2.5f
,-2.5f
, DEPTH
);
271 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f(-2.5f
, 2.5f
, DEPTH
);
272 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f(-2.5f
, 2.5f
,-DEPTH
);
273 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f(-2.5f
,-2.5f
,-DEPTH
);
281 static void Reshape( int width
, int height
)
283 glViewport(0, 0, width
, height
);
284 glMatrixMode(GL_PROJECTION
);
286 gluPerspective(45.0f
, (GLfloat
)(width
)/(GLfloat
)(height
), 0.1f
, 100.0f
);
287 glMatrixMode(GL_MODELVIEW
);
292 static void Key( unsigned char key
, int x
, int y
)
298 fogMode
= SetFogMode(fogMode
+ 1);
301 if (fogDensity
< 1.0) {
307 if (fogDensity
> 0.0) {
313 if (fogStart
> 0.0) {
319 if (fogStart
< fogEnd
) {
325 if (fogEnd
> fogStart
) {
331 if (fogEnd
< 100.0) {
337 fogCoord
= SetFogCoord(fogCoord
^ GL_TRUE
);
347 static void SpecialKey( int key
, int x
, int y
)
353 if (camz
< (DEPTH
- 1.0)) {
367 static void Init( void )
369 have_fog_coord
= glutExtensionSupported("GL_EXT_fog_coord");
371 if (BuildTexture(TEXTURE_FILE
, texture
) == -1) {
375 glEnable(GL_TEXTURE_2D
);
376 glClearColor(0.0f
, 0.0f
, 0.0f
, 0.5f
);
378 glDepthFunc(GL_LEQUAL
);
379 glEnable(GL_DEPTH_TEST
);
380 glShadeModel(GL_SMOOTH
);
381 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_NICEST
);
383 glFogfv(GL_FOG_COLOR
, fogColor
);
384 glHint(GL_FOG_HINT
, GL_NICEST
);
385 fogCoord
= SetFogCoord(GL_TRUE
); /* try to enable fog_coord */
386 fogMode
= SetFogMode(2); /* GL_EXP */
391 glEnableClientState(GL_VERTEX_ARRAY
);
392 glVertexPointer(3, GL_FLOAT
, 0, vertex_pointer
);
394 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
395 glTexCoordPointer(2, GL_FLOAT
, 0, texcoord_pointer
);
397 if (have_fog_coord
) {
398 glFogCoordPointer_ext
= (GLFOGCOORDPOINTEREXTPROC
)glutGetProcAddress("glFogCoordPointerEXT");
399 glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT
);
400 glFogCoordPointer_ext(GL_FLOAT
, 0, fogcoord_pointer
);
406 int main( int argc
, char *argv
[] )
408 glutInit( &argc
, argv
);
409 glutInitWindowPosition( 0, 0 );
410 glutInitWindowSize( 640, 480 );
411 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
412 glutCreateWindow(argv
[0]);
413 glutReshapeFunc( Reshape
);
414 glutKeyboardFunc( Key
);
415 glutSpecialFunc( SpecialKey
);
416 glutDisplayFunc( Display
);