include readtex.h
[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.h"
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 #if !defined(GLAPIENTRYP)
27 # define GLAPIENTRYP *
28 #endif
29
30 typedef void (GLAPIENTRYP GLFOGCOORDFEXTPROC) (GLfloat f);
31 typedef void (GLAPIENTRYP GLFOGCOORDPOINTEREXTPROC) (GLenum, GLsizei, const GLvoid *);
32
33 static GLFOGCOORDFEXTPROC glFogCoordf_ext;
34 #if ARRAYS
35 static GLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext;
36 #endif
37 static GLboolean have_fog_coord;
38
39 static GLfloat camz;
40 static GLuint texture[1];
41
42 static GLint fogMode;
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};
47
48
49 static void APIENTRY glFogCoordf_nop (GLfloat f)
50 {
51 (void)f;
52 }
53
54
55 static int BuildTexture (const char *filename, GLuint texid[])
56 {
57 GLubyte *tex_data;
58 GLenum tex_format;
59 GLint tex_width, tex_height;
60
61 tex_data = LoadRGBImage(filename, &tex_width, &tex_height, &tex_format);
62 if (tex_data == NULL) {
63 return -1;
64 }
65
66 {
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 }
73
74 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);
79
80 glTexImage2D(GL_TEXTURE_2D, 0, tex_format, tex_width, tex_height, 0,
81 tex_format, GL_UNSIGNED_BYTE, tex_data);
82
83 return 0;
84 }
85
86
87 static int SetFogMode (GLint fogMode)
88 {
89 fogMode &= 3;
90 switch (fogMode) {
91 case 0:
92 glDisable(GL_FOG);
93 #if VERBOSE
94 printf("fog(disable)\n");
95 #endif
96 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);
102 #if VERBOSE
103 printf("fog(GL_LINEAR, %.2f, %.2f)\n", fogStart, fogEnd);
104 #endif
105 break;
106 case 2:
107 glEnable(GL_FOG);
108 glFogi(GL_FOG_MODE, GL_EXP);
109 glFogf(GL_FOG_DENSITY, fogDensity);
110 #if VERBOSE
111 printf("fog(GL_EXP, %.2f)\n", fogDensity);
112 #endif
113 break;
114 case 3:
115 glEnable(GL_FOG);
116 glFogi(GL_FOG_MODE, GL_EXP2);
117 glFogf(GL_FOG_DENSITY, fogDensity);
118 #if VERBOSE
119 printf("fog(GL_EXP2, %.2f)\n", fogDensity);
120 #endif
121 break;
122 }
123 return fogMode;
124 }
125
126
127 static GLboolean SetFogCoord (GLboolean fogCoord)
128 {
129 glFogCoordf_ext = glFogCoordf_nop;
130
131 if (!have_fog_coord) {
132 #if VERBOSE
133 printf("fog(GL_FRAGMENT_DEPTH_EXT)%s\n", fogCoord ? " EXT_fog_coord not available!" : "");
134 #endif
135 return GL_FALSE;
136 }
137
138 if (fogCoord) {
139 glFogCoordf_ext = (GLFOGCOORDFEXTPROC)glutGetProcAddress("glFogCoordfEXT");
140 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
141 #if VERBOSE
142 printf("fog(GL_FOG_COORDINATE_EXT)\n");
143 #endif
144 } else {
145 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
146 #if VERBOSE
147 printf("fog(GL_FRAGMENT_DEPTH_EXT)\n");
148 #endif
149 }
150 return fogCoord;
151 }
152
153
154 #if ARRAYS
155 /* could reuse vertices */
156 static 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
173 static 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
190 static 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
207 static 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
226 static 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
281 static 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
292 static 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 '+':
301 if (fogDensity < 1.0) {
302 fogDensity += 0.05;
303 }
304 SetFogMode(fogMode);
305 break;
306 case '-':
307 if (fogDensity > 0.0) {
308 fogDensity -= 0.05;
309 }
310 SetFogMode(fogMode);
311 break;
312 case 's':
313 if (fogStart > 0.0) {
314 fogStart -= 1.0;
315 }
316 SetFogMode(fogMode);
317 break;
318 case 'S':
319 if (fogStart < fogEnd) {
320 fogStart += 1.0;
321 }
322 SetFogMode(fogMode);
323 break;
324 case 'e':
325 if (fogEnd > fogStart) {
326 fogEnd -= 1.0;
327 }
328 SetFogMode(fogMode);
329 break;
330 case 'E':
331 if (fogEnd < 100.0) {
332 fogEnd += 1.0;
333 }
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
347 static 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
367 static 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
406 int 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 }