blob: 19a15f05b87fe2d2c73ebe7a1e421a69a2d60657 [file] [log] [blame]
Daniel Borcaa49a08d2004-02-16 07:31:29 +00001/*
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
11#include <stdio.h>
12#include <stdlib.h>
13#include <math.h>
14#include <GL/glut.h>
15
Brian Paul2d84ed82005-01-09 17:39:06 +000016#include "readtex.h"
Daniel Borcaa49a08d2004-02-16 07:31:29 +000017
18#define TEXTURE_FILE "../images/bw.rgb"
19
20#define ARRAYS 0 /* use glDrawElements */
21
22#define VERBOSE 1 /* tell me what happens */
23
24#define DEPTH 15.0f
Daniel Borcaa49a08d2004-02-16 07:31:29 +000025
Brian Paulb58091a2005-01-09 17:00:57 +000026#if !defined(GLAPIENTRYP)
27# define GLAPIENTRYP *
28#endif
29
Daniel Borcaa49a08d2004-02-16 07:31:29 +000030typedef void (GLAPIENTRYP GLFOGCOORDFEXTPROC) (GLfloat f);
31typedef void (GLAPIENTRYP GLFOGCOORDPOINTEREXTPROC) (GLenum, GLsizei, const GLvoid *);
32
33static GLFOGCOORDFEXTPROC glFogCoordf_ext;
Brian Paul37c04972004-09-16 19:39:04 +000034#if ARRAYS
Daniel Borcaa49a08d2004-02-16 07:31:29 +000035static GLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext;
Brian Paul37c04972004-09-16 19:39:04 +000036#endif
Daniel Borcaa49a08d2004-02-16 07:31:29 +000037static GLboolean have_fog_coord;
38
39static GLfloat camz;
40static GLuint texture[1];
41
42static GLint fogMode;
43static GLboolean fogCoord;
44static GLfloat fogDensity = 0.75;
Daniel Borca2c161cf2004-06-07 06:03:08 +000045static GLfloat fogStart = 1.0, fogEnd = 40.0;
Daniel Borcaa49a08d2004-02-16 07:31:29 +000046static GLfloat fogColor[4] = {0.6f, 0.3f, 0.0f, 1.0f};
47
48
Brian Paul37c04972004-09-16 19:39:04 +000049static void APIENTRY glFogCoordf_nop (GLfloat f)
Daniel Borcaa49a08d2004-02-16 07:31:29 +000050{
Brian Paul37c04972004-09-16 19:39:04 +000051 (void)f;
Daniel Borcaa49a08d2004-02-16 07:31:29 +000052}
53
54
55static int BuildTexture (const char *filename, GLuint texid[])
56{
Brian Paul37c04972004-09-16 19:39:04 +000057 GLubyte *tex_data;
58 GLenum tex_format;
59 GLint tex_width, tex_height;
Daniel Borcaa49a08d2004-02-16 07:31:29 +000060
Brian Paul37c04972004-09-16 19:39:04 +000061 tex_data = LoadRGBImage(filename, &tex_width, &tex_height, &tex_format);
62 if (tex_data == NULL) {
63 return -1;
64 }
Daniel Borcaa49a08d2004-02-16 07:31:29 +000065
Brian Paul37c04972004-09-16 19:39:04 +000066 {
67 GLint tex_max;
68 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &tex_max);
69 if ((tex_width > tex_max) || (tex_height > tex_max)) {
70 return -1;
71 }
72 }
Daniel Borcaa49a08d2004-02-16 07:31:29 +000073
Brian Paul37c04972004-09-16 19:39:04 +000074 glGenTextures(1, texid);
75
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);
Daniel Borcaa49a08d2004-02-16 07:31:29 +000079
Brian Paul37c04972004-09-16 19:39:04 +000080 glTexImage2D(GL_TEXTURE_2D, 0, tex_format, tex_width, tex_height, 0,
81 tex_format, GL_UNSIGNED_BYTE, tex_data);
Daniel Borcaa49a08d2004-02-16 07:31:29 +000082
Brian Paul37c04972004-09-16 19:39:04 +000083 return 0;
Daniel Borcaa49a08d2004-02-16 07:31:29 +000084}
85
86
87static int SetFogMode (GLint fogMode)
88{
Brian Paul37c04972004-09-16 19:39:04 +000089 fogMode &= 3;
90 switch (fogMode) {
91 case 0:
92 glDisable(GL_FOG);
Daniel Borcaa49a08d2004-02-16 07:31:29 +000093#if VERBOSE
Brian Paul37c04972004-09-16 19:39:04 +000094 printf("fog(disable)\n");
Daniel Borcaa49a08d2004-02-16 07:31:29 +000095#endif
Brian Paul37c04972004-09-16 19:39:04 +000096 break;
97 case 1:
98 glEnable(GL_FOG);
99 glFogi(GL_FOG_MODE, GL_LINEAR);
100 glFogf(GL_FOG_START, fogStart);
101 glFogf(GL_FOG_END, fogEnd);
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000102#if VERBOSE
Brian Paul37c04972004-09-16 19:39:04 +0000103 printf("fog(GL_LINEAR, %.2f, %.2f)\n", fogStart, fogEnd);
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000104#endif
Brian Paul37c04972004-09-16 19:39:04 +0000105 break;
106 case 2:
107 glEnable(GL_FOG);
108 glFogi(GL_FOG_MODE, GL_EXP);
109 glFogf(GL_FOG_DENSITY, fogDensity);
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000110#if VERBOSE
Brian Paul37c04972004-09-16 19:39:04 +0000111 printf("fog(GL_EXP, %.2f)\n", fogDensity);
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000112#endif
Brian Paul37c04972004-09-16 19:39:04 +0000113 break;
114 case 3:
115 glEnable(GL_FOG);
116 glFogi(GL_FOG_MODE, GL_EXP2);
117 glFogf(GL_FOG_DENSITY, fogDensity);
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000118#if VERBOSE
Brian Paul37c04972004-09-16 19:39:04 +0000119 printf("fog(GL_EXP2, %.2f)\n", fogDensity);
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000120#endif
Brian Paul37c04972004-09-16 19:39:04 +0000121 break;
122 }
123 return fogMode;
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000124}
125
126
127static GLboolean SetFogCoord (GLboolean fogCoord)
128{
Brian Paul37c04972004-09-16 19:39:04 +0000129 glFogCoordf_ext = glFogCoordf_nop;
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000130
Brian Paul37c04972004-09-16 19:39:04 +0000131 if (!have_fog_coord) {
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000132#if VERBOSE
Brian Paul37c04972004-09-16 19:39:04 +0000133 printf("fog(GL_FRAGMENT_DEPTH_EXT)%s\n", fogCoord ? " EXT_fog_coord not available!" : "");
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000134#endif
Brian Paul37c04972004-09-16 19:39:04 +0000135 return GL_FALSE;
136 }
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000137
Brian Paul37c04972004-09-16 19:39:04 +0000138 if (fogCoord) {
139 glFogCoordf_ext = (GLFOGCOORDFEXTPROC)glutGetProcAddress("glFogCoordfEXT");
140 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000141#if VERBOSE
Brian Paul37c04972004-09-16 19:39:04 +0000142 printf("fog(GL_FOG_COORDINATE_EXT)\n");
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000143#endif
Brian Paul37c04972004-09-16 19:39:04 +0000144 } else {
145 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000146#if VERBOSE
Brian Paul37c04972004-09-16 19:39:04 +0000147 printf("fog(GL_FRAGMENT_DEPTH_EXT)\n");
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000148#endif
Brian Paul37c04972004-09-16 19:39:04 +0000149 }
150 return fogCoord;
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000151}
152
153
154#if ARRAYS
155/* could reuse vertices */
156static GLuint vertex_index[] = {
157 /* Back */
158 0, 1, 2, 3,
159
160 /* Floor */
161 4, 5, 6, 7,
162
163 /* Roof */
164 8, 9, 10, 11,
165
166 /* Right */
167 12, 13, 14, 15,
168
169 /* Left */
170 16, 17, 18, 19
171};
172
173static GLfloat vertex_pointer[][3] = {
174 /* Back */
175 {-2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH}, { 2.5f, 2.5f,-DEPTH}, {-2.5f, 2.5f,-DEPTH},
176
177 /* Floor */
178 {-2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f, DEPTH}, {-2.5f,-2.5f, DEPTH},
179
180 /* Roof */
181 {-2.5f, 2.5f,-DEPTH}, { 2.5f, 2.5f,-DEPTH}, { 2.5f, 2.5f, DEPTH}, {-2.5f, 2.5f, DEPTH},
182
183 /* Right */
184 { 2.5f,-2.5f, DEPTH}, { 2.5f, 2.5f, DEPTH}, { 2.5f, 2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH},
185
186 /* Left */
187 {-2.5f,-2.5f, DEPTH}, {-2.5f, 2.5f, DEPTH}, {-2.5f, 2.5f,-DEPTH}, {-2.5f,-2.5f,-DEPTH}
188};
189
190static GLfloat texcoord_pointer[][2] = {
191 /* Back */
192 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
193
194 /* Floor */
195 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
196
197 /* Roof */
198 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
199
200 /* Right */
201 {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f},
202
203 /* Left */
204 {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}
205};
206
207static GLfloat fogcoord_pointer[][1] = {
208 /* Back */
209 {1.0f}, {1.0f}, {1.0f}, {1.0f},
210
211 /* Floor */
212 {1.0f}, {1.0f}, {0.0f}, {0.0f},
213
214 /* Roof */
215 {1.0f}, {1.0f}, {0.0f}, {0.0f},
216
217 /* Right */
218 {0.0f}, {0.0f}, {1.0f}, {1.0f},
219
220 /* Left */
221 {0.0f}, {0.0f}, {1.0f}, {1.0f}
222};
223#endif
224
225
226static void Display( void )
227{
228 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
229 glLoadIdentity ();
230
231 glTranslatef(0.0f, 0.0f, camz);
232
233#if ARRAYS
234 glDrawElements(GL_QUADS, sizeof(vertex_index) / sizeof(vertex_index[0]), GL_UNSIGNED_INT, vertex_index);
235#else
236 /* Back */
237 glBegin(GL_QUADS);
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);
242 glEnd();
243
244 /* Floor */
245 glBegin(GL_QUADS);
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);
250 glEnd();
251
252 /* Roof */
253 glBegin(GL_QUADS);
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);
258 glEnd();
259
260 /* Right */
261 glBegin(GL_QUADS);
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);
266 glEnd();
267
268 /* Left */
269 glBegin(GL_QUADS);
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);
274 glEnd();
275#endif
276
277 glutSwapBuffers();
278}
279
280
281static void Reshape( int width, int height )
282{
283 glViewport(0, 0, width, height);
284 glMatrixMode(GL_PROJECTION);
285 glLoadIdentity();
286 gluPerspective(45.0f, (GLfloat)(width)/(GLfloat)(height), 0.1f, 100.0f);
287 glMatrixMode(GL_MODELVIEW);
288 glLoadIdentity();
289}
290
291
292static void Key( unsigned char key, int x, int y )
293{
294 (void) x;
295 (void) y;
296 switch (key) {
297 case 'f':
298 fogMode = SetFogMode(fogMode + 1);
299 break;
300 case '+':
Daniel Borca2c161cf2004-06-07 06:03:08 +0000301 if (fogDensity < 1.0) {
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000302 fogDensity += 0.05;
303 }
304 SetFogMode(fogMode);
305 break;
306 case '-':
Daniel Borca2c161cf2004-06-07 06:03:08 +0000307 if (fogDensity > 0.0) {
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000308 fogDensity -= 0.05;
309 }
310 SetFogMode(fogMode);
311 break;
312 case 's':
Daniel Borca2c161cf2004-06-07 06:03:08 +0000313 if (fogStart > 0.0) {
314 fogStart -= 1.0;
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000315 }
316 SetFogMode(fogMode);
317 break;
318 case 'S':
Daniel Borca2c161cf2004-06-07 06:03:08 +0000319 if (fogStart < fogEnd) {
320 fogStart += 1.0;
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000321 }
322 SetFogMode(fogMode);
323 break;
324 case 'e':
Daniel Borca2c161cf2004-06-07 06:03:08 +0000325 if (fogEnd > fogStart) {
326 fogEnd -= 1.0;
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000327 }
328 SetFogMode(fogMode);
329 break;
330 case 'E':
Daniel Borca2c161cf2004-06-07 06:03:08 +0000331 if (fogEnd < 100.0) {
332 fogEnd += 1.0;
Daniel Borcaa49a08d2004-02-16 07:31:29 +0000333 }
334 SetFogMode(fogMode);
335 break;
336 case 'c':
337 fogCoord = SetFogCoord(fogCoord ^ GL_TRUE);
338 break;
339 case 27:
340 exit(0);
341 break;
342 }
343 glutPostRedisplay();
344}
345
346
347static void SpecialKey( int key, int x, int y )
348{
349 (void) x;
350 (void) y;
351 switch (key) {
352 case GLUT_KEY_UP:
353 if (camz < (DEPTH - 1.0)) {
354 camz += 1.0f;
355 }
356 break;
357 case GLUT_KEY_DOWN:
358 if (camz > -19.0) {
359 camz -= 1.0f;
360 }
361 break;
362 }
363 glutPostRedisplay();
364}
365
366
367static void Init( void )
368{
369 have_fog_coord = glutExtensionSupported("GL_EXT_fog_coord");
370
371 if (BuildTexture(TEXTURE_FILE, texture) == -1) {
372 exit(1);
373 }
374
375 glEnable(GL_TEXTURE_2D);
376 glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
377 glClearDepth(1.0f);
378 glDepthFunc(GL_LEQUAL);
379 glEnable(GL_DEPTH_TEST);
380 glShadeModel(GL_SMOOTH);
381 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
382
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 */
387
388 camz = -19.0f;
389
390#if ARRAYS
391 glEnableClientState(GL_VERTEX_ARRAY);
392 glVertexPointer(3, GL_FLOAT, 0, vertex_pointer);
393
394 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
395 glTexCoordPointer(2, GL_FLOAT, 0, texcoord_pointer);
396
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);
401 }
402#endif
403}
404
405
406int main( int argc, char *argv[] )
407{
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 );
417 Init();
418 glutMainLoop();
419 return 0;
420}