4 * Based on glutskel.c by Brian Paul
5 * and NeHe's Volumetric fog tutorial!
16 #include "readtex.c" /* the compulsory hack */
18 #define TEXTURE_FILE "../images/bw.rgb"
20 #define ARRAYS 0 /* use glDrawElements */
22 #define VERBOSE 1 /* tell me what happens */
26 typedef void (GLAPIENTRYP GLFOGCOORDFEXTPROC
) (GLfloat f
);
27 typedef void (GLAPIENTRYP GLFOGCOORDPOINTEREXTPROC
) (GLenum
, GLsizei
, const GLvoid
*);
29 static GLFOGCOORDFEXTPROC glFogCoordf_ext
;
30 static GLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext
;
31 static GLboolean have_fog_coord
;
34 static GLuint texture
[1];
37 static GLboolean fogCoord
;
38 static GLfloat fogDensity
= 0.75;
39 static GLfloat fogStart
= 1.0, fogEnd
= 40.0;
40 static GLfloat fogColor
[4] = {0.6f
, 0.3f
, 0.0f
, 1.0f
};
43 void APIENTRY
glFogCoordf_nop (GLfloat f
)
49 static int BuildTexture (const char *filename
, GLuint texid
[])
53 GLint tex_width
, tex_height
;
55 tex_data
= LoadRGBImage(filename
, &tex_width
, &tex_height
, &tex_format
);
56 if (tex_data
== NULL
) {
62 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &tex_max
);
63 if ((tex_width
> tex_max
) || (tex_height
> tex_max
)) {
68 glGenTextures(1, texid
);
70 glBindTexture(GL_TEXTURE_2D
, texid
[0]);
71 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
72 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
74 glTexImage2D(GL_TEXTURE_2D
, 0, tex_format
, tex_width
, tex_height
, 0, tex_format
, GL_UNSIGNED_BYTE
, tex_data
);
80 static int SetFogMode (GLint fogMode
)
87 printf("fog(disable)\n");
92 glFogi(GL_FOG_MODE
, GL_LINEAR
);
93 glFogf(GL_FOG_START
, fogStart
);
94 glFogf(GL_FOG_END
, fogEnd
);
96 printf("fog(GL_LINEAR, %.2f, %.2f)\n", fogStart
, fogEnd
);
101 glFogi(GL_FOG_MODE
, GL_EXP
);
102 glFogf(GL_FOG_DENSITY
, fogDensity
);
104 printf("fog(GL_EXP, %.2f)\n", fogDensity
);
109 glFogi(GL_FOG_MODE
, GL_EXP2
);
110 glFogf(GL_FOG_DENSITY
, fogDensity
);
112 printf("fog(GL_EXP2, %.2f)\n", fogDensity
);
120 static GLboolean
SetFogCoord (GLboolean fogCoord
)
122 glFogCoordf_ext
= glFogCoordf_nop
;
124 if (!have_fog_coord
) {
126 printf("fog(GL_FRAGMENT_DEPTH_EXT)%s\n", fogCoord
? " EXT_fog_coord not available!" : "");
132 glFogCoordf_ext
= (GLFOGCOORDFEXTPROC
)glutGetProcAddress("glFogCoordfEXT");
133 glFogi(GL_FOG_COORDINATE_SOURCE_EXT
, GL_FOG_COORDINATE_EXT
);
135 printf("fog(GL_FOG_COORDINATE_EXT)\n");
138 glFogi(GL_FOG_COORDINATE_SOURCE_EXT
, GL_FRAGMENT_DEPTH_EXT
);
140 printf("fog(GL_FRAGMENT_DEPTH_EXT)\n");
148 /* could reuse vertices */
149 static GLuint vertex_index
[] = {
166 static GLfloat vertex_pointer
[][3] = {
168 {-2.5f
,-2.5f
,-DEPTH
}, { 2.5f
,-2.5f
,-DEPTH
}, { 2.5f
, 2.5f
,-DEPTH
}, {-2.5f
, 2.5f
,-DEPTH
},
171 {-2.5f
,-2.5f
,-DEPTH
}, { 2.5f
,-2.5f
,-DEPTH
}, { 2.5f
,-2.5f
, DEPTH
}, {-2.5f
,-2.5f
, DEPTH
},
174 {-2.5f
, 2.5f
,-DEPTH
}, { 2.5f
, 2.5f
,-DEPTH
}, { 2.5f
, 2.5f
, DEPTH
}, {-2.5f
, 2.5f
, DEPTH
},
177 { 2.5f
,-2.5f
, DEPTH
}, { 2.5f
, 2.5f
, DEPTH
}, { 2.5f
, 2.5f
,-DEPTH
}, { 2.5f
,-2.5f
,-DEPTH
},
180 {-2.5f
,-2.5f
, DEPTH
}, {-2.5f
, 2.5f
, DEPTH
}, {-2.5f
, 2.5f
,-DEPTH
}, {-2.5f
,-2.5f
,-DEPTH
}
183 static GLfloat texcoord_pointer
[][2] = {
185 {0.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 1.0f
},
188 {0.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 1.0f
},
191 {0.0f
, 0.0f
}, {1.0f
, 0.0f
}, {1.0f
, 1.0f
}, {0.0f
, 1.0f
},
194 {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
},
197 {0.0f
, 0.0f
}, {0.0f
, 1.0f
}, {1.0f
, 1.0f
}, {1.0f
, 0.0f
}
200 static GLfloat fogcoord_pointer
[][1] = {
202 {1.0f
}, {1.0f
}, {1.0f
}, {1.0f
},
205 {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
},
208 {1.0f
}, {1.0f
}, {0.0f
}, {0.0f
},
211 {0.0f
}, {0.0f
}, {1.0f
}, {1.0f
},
214 {0.0f
}, {0.0f
}, {1.0f
}, {1.0f
}
219 static void Display( void )
221 glClear (GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
224 glTranslatef(0.0f
, 0.0f
, camz
);
227 glDrawElements(GL_QUADS
, sizeof(vertex_index
) / sizeof(vertex_index
[0]), GL_UNSIGNED_INT
, vertex_index
);
231 glFogCoordf_ext(1.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f(-2.5f
,-2.5f
,-DEPTH
);
232 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f( 2.5f
,-2.5f
,-DEPTH
);
233 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f( 2.5f
, 2.5f
,-DEPTH
);
234 glFogCoordf_ext(1.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f(-2.5f
, 2.5f
,-DEPTH
);
239 glFogCoordf_ext(1.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f(-2.5f
,-2.5f
,-DEPTH
);
240 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f( 2.5f
,-2.5f
,-DEPTH
);
241 glFogCoordf_ext(0.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f( 2.5f
,-2.5f
, DEPTH
);
242 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f(-2.5f
,-2.5f
, DEPTH
);
247 glFogCoordf_ext(1.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f(-2.5f
, 2.5f
,-DEPTH
);
248 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f( 2.5f
, 2.5f
,-DEPTH
);
249 glFogCoordf_ext(0.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f( 2.5f
, 2.5f
, DEPTH
);
250 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f(-2.5f
, 2.5f
, DEPTH
);
255 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f( 2.5f
,-2.5f
, DEPTH
);
256 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f( 2.5f
, 2.5f
, DEPTH
);
257 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f( 2.5f
, 2.5f
,-DEPTH
);
258 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f( 2.5f
,-2.5f
,-DEPTH
);
263 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 0.0f
); glVertex3f(-2.5f
,-2.5f
, DEPTH
);
264 glFogCoordf_ext(0.0f
); glTexCoord2f(0.0f
, 1.0f
); glVertex3f(-2.5f
, 2.5f
, DEPTH
);
265 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 1.0f
); glVertex3f(-2.5f
, 2.5f
,-DEPTH
);
266 glFogCoordf_ext(1.0f
); glTexCoord2f(1.0f
, 0.0f
); glVertex3f(-2.5f
,-2.5f
,-DEPTH
);
274 static void Reshape( int width
, int height
)
276 glViewport(0, 0, width
, height
);
277 glMatrixMode(GL_PROJECTION
);
279 gluPerspective(45.0f
, (GLfloat
)(width
)/(GLfloat
)(height
), 0.1f
, 100.0f
);
280 glMatrixMode(GL_MODELVIEW
);
285 static void Key( unsigned char key
, int x
, int y
)
291 fogMode
= SetFogMode(fogMode
+ 1);
294 if (fogDensity
< 1.0) {
300 if (fogDensity
> 0.0) {
306 if (fogStart
> 0.0) {
312 if (fogStart
< fogEnd
) {
318 if (fogEnd
> fogStart
) {
324 if (fogEnd
< 100.0) {
330 fogCoord
= SetFogCoord(fogCoord
^ GL_TRUE
);
340 static void SpecialKey( int key
, int x
, int y
)
346 if (camz
< (DEPTH
- 1.0)) {
360 static void Init( void )
362 have_fog_coord
= glutExtensionSupported("GL_EXT_fog_coord");
364 if (BuildTexture(TEXTURE_FILE
, texture
) == -1) {
368 glEnable(GL_TEXTURE_2D
);
369 glClearColor(0.0f
, 0.0f
, 0.0f
, 0.5f
);
371 glDepthFunc(GL_LEQUAL
);
372 glEnable(GL_DEPTH_TEST
);
373 glShadeModel(GL_SMOOTH
);
374 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_NICEST
);
376 glFogfv(GL_FOG_COLOR
, fogColor
);
377 glHint(GL_FOG_HINT
, GL_NICEST
);
378 fogCoord
= SetFogCoord(GL_TRUE
); /* try to enable fog_coord */
379 fogMode
= SetFogMode(2); /* GL_EXP */
384 glEnableClientState(GL_VERTEX_ARRAY
);
385 glVertexPointer(3, GL_FLOAT
, 0, vertex_pointer
);
387 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
388 glTexCoordPointer(2, GL_FLOAT
, 0, texcoord_pointer
);
390 if (have_fog_coord
) {
391 glFogCoordPointer_ext
= (GLFOGCOORDPOINTEREXTPROC
)glutGetProcAddress("glFogCoordPointerEXT");
392 glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT
);
393 glFogCoordPointer_ext(GL_FLOAT
, 0, fogcoord_pointer
);
399 int main( int argc
, char *argv
[] )
401 glutInit( &argc
, argv
);
402 glutInitWindowPosition( 0, 0 );
403 glutInitWindowSize( 640, 480 );
404 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
405 glutCreateWindow(argv
[0]);
406 glutReshapeFunc( Reshape
);
407 glutKeyboardFunc( Key
);
408 glutSpecialFunc( SpecialKey
);
409 glutDisplayFunc( Display
);