small corrections
[mesa.git] / progs / demos / fogcoord.c
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
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14 #include <GL/glut.h>
15
16 #include "readtex.c" /* the compulsory hack */
17
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
25
26 typedef void (GLAPIENTRYP GLFOGCOORDFEXTPROC) (GLfloat f);
27 typedef void (GLAPIENTRYP GLFOGCOORDPOINTEREXTPROC) (GLenum, GLsizei, const GLvoid *);
28
29 static GLFOGCOORDFEXTPROC glFogCoordf_ext;
30 static GLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext;
31 static GLboolean have_fog_coord;
32
33 static GLfloat camz;
34 static GLuint texture[1];
35
36 static GLint fogMode;
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};
41
42
43 void APIENTRY glFogCoordf_nop (GLfloat f)
44 {
45 (void)f;
46 }
47
48
49 static int BuildTexture (const char *filename, GLuint texid[])
50 {
51 GLubyte *tex_data;
52 GLenum tex_format;
53 GLint tex_width, tex_height;
54
55 tex_data = LoadRGBImage(filename, &tex_width, &tex_height, &tex_format);
56 if (tex_data == NULL) {
57 return -1;
58 }
59
60 {
61 GLint tex_max;
62 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &tex_max);
63 if ((tex_width > tex_max) || (tex_height > tex_max)) {
64 return -1;
65 }
66 }
67
68 glGenTextures(1, texid);
69
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);
73
74 glTexImage2D(GL_TEXTURE_2D, 0, tex_format, tex_width, tex_height, 0, tex_format, GL_UNSIGNED_BYTE, tex_data);
75
76 return 0;
77 }
78
79
80 static int SetFogMode (GLint fogMode)
81 {
82 fogMode &= 3;
83 switch (fogMode) {
84 case 0:
85 glDisable(GL_FOG);
86 #if VERBOSE
87 printf("fog(disable)\n");
88 #endif
89 break;
90 case 1:
91 glEnable(GL_FOG);
92 glFogi(GL_FOG_MODE, GL_LINEAR);
93 glFogf(GL_FOG_START, fogStart);
94 glFogf(GL_FOG_END, fogEnd);
95 #if VERBOSE
96 printf("fog(GL_LINEAR, %.2f, %.2f)\n", fogStart, fogEnd);
97 #endif
98 break;
99 case 2:
100 glEnable(GL_FOG);
101 glFogi(GL_FOG_MODE, GL_EXP);
102 glFogf(GL_FOG_DENSITY, fogDensity);
103 #if VERBOSE
104 printf("fog(GL_EXP, %.2f)\n", fogDensity);
105 #endif
106 break;
107 case 3:
108 glEnable(GL_FOG);
109 glFogi(GL_FOG_MODE, GL_EXP2);
110 glFogf(GL_FOG_DENSITY, fogDensity);
111 #if VERBOSE
112 printf("fog(GL_EXP2, %.2f)\n", fogDensity);
113 #endif
114 break;
115 }
116 return fogMode;
117 }
118
119
120 static GLboolean SetFogCoord (GLboolean fogCoord)
121 {
122 glFogCoordf_ext = glFogCoordf_nop;
123
124 if (!have_fog_coord) {
125 #if VERBOSE
126 printf("fog(GL_FRAGMENT_DEPTH_EXT)%s\n", fogCoord ? " EXT_fog_coord not available!" : "");
127 #endif
128 return GL_FALSE;
129 }
130
131 if (fogCoord) {
132 glFogCoordf_ext = (GLFOGCOORDFEXTPROC)glutGetProcAddress("glFogCoordfEXT");
133 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
134 #if VERBOSE
135 printf("fog(GL_FOG_COORDINATE_EXT)\n");
136 #endif
137 } else {
138 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
139 #if VERBOSE
140 printf("fog(GL_FRAGMENT_DEPTH_EXT)\n");
141 #endif
142 }
143 return fogCoord;
144 }
145
146
147 #if ARRAYS
148 /* could reuse vertices */
149 static GLuint vertex_index[] = {
150 /* Back */
151 0, 1, 2, 3,
152
153 /* Floor */
154 4, 5, 6, 7,
155
156 /* Roof */
157 8, 9, 10, 11,
158
159 /* Right */
160 12, 13, 14, 15,
161
162 /* Left */
163 16, 17, 18, 19
164 };
165
166 static GLfloat vertex_pointer[][3] = {
167 /* Back */
168 {-2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH}, { 2.5f, 2.5f,-DEPTH}, {-2.5f, 2.5f,-DEPTH},
169
170 /* Floor */
171 {-2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH}, { 2.5f,-2.5f, DEPTH}, {-2.5f,-2.5f, DEPTH},
172
173 /* Roof */
174 {-2.5f, 2.5f,-DEPTH}, { 2.5f, 2.5f,-DEPTH}, { 2.5f, 2.5f, DEPTH}, {-2.5f, 2.5f, DEPTH},
175
176 /* Right */
177 { 2.5f,-2.5f, DEPTH}, { 2.5f, 2.5f, DEPTH}, { 2.5f, 2.5f,-DEPTH}, { 2.5f,-2.5f,-DEPTH},
178
179 /* Left */
180 {-2.5f,-2.5f, DEPTH}, {-2.5f, 2.5f, DEPTH}, {-2.5f, 2.5f,-DEPTH}, {-2.5f,-2.5f,-DEPTH}
181 };
182
183 static GLfloat texcoord_pointer[][2] = {
184 /* Back */
185 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
186
187 /* Floor */
188 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
189
190 /* Roof */
191 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
192
193 /* Right */
194 {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f},
195
196 /* Left */
197 {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}
198 };
199
200 static GLfloat fogcoord_pointer[][1] = {
201 /* Back */
202 {1.0f}, {1.0f}, {1.0f}, {1.0f},
203
204 /* Floor */
205 {1.0f}, {1.0f}, {0.0f}, {0.0f},
206
207 /* Roof */
208 {1.0f}, {1.0f}, {0.0f}, {0.0f},
209
210 /* Right */
211 {0.0f}, {0.0f}, {1.0f}, {1.0f},
212
213 /* Left */
214 {0.0f}, {0.0f}, {1.0f}, {1.0f}
215 };
216 #endif
217
218
219 static void Display( void )
220 {
221 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
222 glLoadIdentity ();
223
224 glTranslatef(0.0f, 0.0f, camz);
225
226 #if ARRAYS
227 glDrawElements(GL_QUADS, sizeof(vertex_index) / sizeof(vertex_index[0]), GL_UNSIGNED_INT, vertex_index);
228 #else
229 /* Back */
230 glBegin(GL_QUADS);
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);
235 glEnd();
236
237 /* Floor */
238 glBegin(GL_QUADS);
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);
243 glEnd();
244
245 /* Roof */
246 glBegin(GL_QUADS);
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);
251 glEnd();
252
253 /* Right */
254 glBegin(GL_QUADS);
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);
259 glEnd();
260
261 /* Left */
262 glBegin(GL_QUADS);
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);
267 glEnd();
268 #endif
269
270 glutSwapBuffers();
271 }
272
273
274 static void Reshape( int width, int height )
275 {
276 glViewport(0, 0, width, height);
277 glMatrixMode(GL_PROJECTION);
278 glLoadIdentity();
279 gluPerspective(45.0f, (GLfloat)(width)/(GLfloat)(height), 0.1f, 100.0f);
280 glMatrixMode(GL_MODELVIEW);
281 glLoadIdentity();
282 }
283
284
285 static void Key( unsigned char key, int x, int y )
286 {
287 (void) x;
288 (void) y;
289 switch (key) {
290 case 'f':
291 fogMode = SetFogMode(fogMode + 1);
292 break;
293 case '+':
294 if (fogDensity < 1.0) {
295 fogDensity += 0.05;
296 }
297 SetFogMode(fogMode);
298 break;
299 case '-':
300 if (fogDensity > 0.0) {
301 fogDensity -= 0.05;
302 }
303 SetFogMode(fogMode);
304 break;
305 case 's':
306 if (fogStart > 0.0) {
307 fogStart -= 1.0;
308 }
309 SetFogMode(fogMode);
310 break;
311 case 'S':
312 if (fogStart < fogEnd) {
313 fogStart += 1.0;
314 }
315 SetFogMode(fogMode);
316 break;
317 case 'e':
318 if (fogEnd > fogStart) {
319 fogEnd -= 1.0;
320 }
321 SetFogMode(fogMode);
322 break;
323 case 'E':
324 if (fogEnd < 100.0) {
325 fogEnd += 1.0;
326 }
327 SetFogMode(fogMode);
328 break;
329 case 'c':
330 fogCoord = SetFogCoord(fogCoord ^ GL_TRUE);
331 break;
332 case 27:
333 exit(0);
334 break;
335 }
336 glutPostRedisplay();
337 }
338
339
340 static void SpecialKey( int key, int x, int y )
341 {
342 (void) x;
343 (void) y;
344 switch (key) {
345 case GLUT_KEY_UP:
346 if (camz < (DEPTH - 1.0)) {
347 camz += 1.0f;
348 }
349 break;
350 case GLUT_KEY_DOWN:
351 if (camz > -19.0) {
352 camz -= 1.0f;
353 }
354 break;
355 }
356 glutPostRedisplay();
357 }
358
359
360 static void Init( void )
361 {
362 have_fog_coord = glutExtensionSupported("GL_EXT_fog_coord");
363
364 if (BuildTexture(TEXTURE_FILE, texture) == -1) {
365 exit(1);
366 }
367
368 glEnable(GL_TEXTURE_2D);
369 glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
370 glClearDepth(1.0f);
371 glDepthFunc(GL_LEQUAL);
372 glEnable(GL_DEPTH_TEST);
373 glShadeModel(GL_SMOOTH);
374 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
375
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 */
380
381 camz = -19.0f;
382
383 #if ARRAYS
384 glEnableClientState(GL_VERTEX_ARRAY);
385 glVertexPointer(3, GL_FLOAT, 0, vertex_pointer);
386
387 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
388 glTexCoordPointer(2, GL_FLOAT, 0, texcoord_pointer);
389
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);
394 }
395 #endif
396 }
397
398
399 int main( int argc, char *argv[] )
400 {
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 );
410 Init();
411 glutMainLoop();
412 return 0;
413 }