Merge branch 'mesa_7_7_branch'
[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 #include <stdio.h>
11 #include <stdlib.h>
12 #include <math.h>
13 #include <GL/glew.h>
14 #include <GL/glut.h>
15
16 #define DEPTH 5.0f
17
18 static GLfloat camz;
19
20 static GLint fogMode;
21 static GLboolean fogCoord;
22 static GLfloat fogDensity = 0.75;
23 static GLfloat fogStart = 1.0, fogEnd = DEPTH;
24 static GLfloat fogColor[4] = {0.6f, 0.3f, 0.0f, 1.0f};
25 static const char *ModeStr = NULL;
26 static GLboolean Arrays = GL_FALSE;
27 static GLboolean Texture = GL_TRUE;
28
29
30 static void
31 Reset(void)
32 {
33 fogMode = 1;
34 fogCoord = 1;
35 fogDensity = 0.75;
36 fogStart = 1.0;
37 fogEnd = DEPTH;
38 Arrays = GL_FALSE;
39 Texture = GL_TRUE;
40 }
41
42
43 static void
44 glFogCoordf_ext (GLfloat f)
45 {
46 if (fogCoord)
47 glFogCoordfEXT(f);
48 }
49
50
51 static void
52 PrintString(const char *s)
53 {
54 while (*s) {
55 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
56 s++;
57 }
58 }
59
60
61 static void
62 PrintInfo(void)
63 {
64 char s[100];
65
66 glDisable(GL_FOG);
67 glColor3f(0, 1, 1);
68
69 sprintf(s, "Mode(m): %s Start(s/S): %g End(e/E): %g Density(d/D): %g",
70 ModeStr, fogStart, fogEnd, fogDensity);
71 glWindowPos2iARB(5, 20);
72 PrintString(s);
73
74 sprintf(s, "Arrays(a): %s glFogCoord(c): %s EyeZ(z/z): %g",
75 (Arrays ? "Yes" : "No"),
76 (fogCoord ? "Yes" : "No"),
77 camz);
78 glWindowPos2iARB(5, 5);
79 PrintString(s);
80 }
81
82
83 static int
84 SetFogMode(GLint fogMode)
85 {
86 fogMode &= 3;
87 switch (fogMode) {
88 case 0:
89 ModeStr = "Off";
90 glDisable(GL_FOG);
91 break;
92 case 1:
93 ModeStr = "GL_LINEAR";
94 glEnable(GL_FOG);
95 glFogi(GL_FOG_MODE, GL_LINEAR);
96 glFogf(GL_FOG_START, fogStart);
97 glFogf(GL_FOG_END, fogEnd);
98 break;
99 case 2:
100 ModeStr = "GL_EXP";
101 glEnable(GL_FOG);
102 glFogi(GL_FOG_MODE, GL_EXP);
103 glFogf(GL_FOG_DENSITY, fogDensity);
104 break;
105 case 3:
106 ModeStr = "GL_EXP2";
107 glEnable(GL_FOG);
108 glFogi(GL_FOG_MODE, GL_EXP2);
109 glFogf(GL_FOG_DENSITY, fogDensity);
110 break;
111 }
112 return fogMode;
113 }
114
115
116 static GLboolean
117 SetFogCoord(GLboolean fogCoord)
118 {
119 if (!GLEW_EXT_fog_coord) {
120 return GL_FALSE;
121 }
122
123 if (fogCoord) {
124 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
125 }
126 else {
127 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
128 }
129 return fogCoord;
130 }
131
132
133 /* could reuse vertices */
134 static GLuint vertex_index[] = {
135 /* Back */
136 0, 1, 2, 3,
137
138 /* Floor */
139 4, 5, 6, 7,
140
141 /* Roof */
142 8, 9, 10, 11,
143
144 /* Right */
145 12, 13, 14, 15,
146
147 /* Left */
148 16, 17, 18, 19
149 };
150
151 static GLfloat vertex_pointer[][3] = {
152 /* Back */
153 {-1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, { 1.0f, 1.0f,-DEPTH}, {-1.0f, 1.0f,-DEPTH},
154
155 /* Floor */
156 {-1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH}, { 1.0f,-1.0f, 0.0}, {-1.0f,-1.0f, 0.0},
157
158 /* Roof */
159 {-1.0f, 1.0f,-DEPTH}, { 1.0f, 1.0f,-DEPTH}, { 1.0f, 1.0f, 0.0}, {-1.0f, 1.0f, 0.0},
160
161 /* Right */
162 { 1.0f,-1.0f, 0.0}, { 1.0f, 1.0f, 0.0}, { 1.0f, 1.0f,-DEPTH}, { 1.0f,-1.0f,-DEPTH},
163
164 /* Left */
165 {-1.0f,-1.0f, 0.0}, {-1.0f, 1.0f, 0.0}, {-1.0f, 1.0f,-DEPTH}, {-1.0f,-1.0f,-DEPTH}
166 };
167
168 static GLfloat texcoord_pointer[][2] = {
169 /* Back */
170 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
171
172 /* Floor */
173 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, DEPTH}, {0.0f, DEPTH},
174
175 /* Roof */
176 {1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, DEPTH}, {1.0f, DEPTH},
177
178 /* Right */
179 {0.0f, 1.0f}, {0.0f, 0.0f}, {DEPTH, 0.0f}, {DEPTH, 1.0f},
180
181 /* Left */
182 {0.0f, 0.0f}, {0.0f, 1.0f}, {DEPTH, 1.0f}, {DEPTH, 0.0f}
183 };
184
185 static GLfloat fogcoord_pointer[] = {
186 /* Back */
187 DEPTH, DEPTH, DEPTH, DEPTH,
188
189 /* Floor */
190 DEPTH, DEPTH, 0.0, 0.0,
191
192 /* Roof */
193 DEPTH, DEPTH, 0.0, 0.0,
194
195 /* Right */
196 0.0, 0.0, DEPTH, DEPTH,
197
198 /* Left */
199 0.0, 0.0, DEPTH, DEPTH
200 };
201
202
203 static void
204 Display( void )
205 {
206 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
207 glLoadIdentity ();
208
209 glTranslatef(0.0f, 0.0f, -camz);
210
211 SetFogMode(fogMode);
212
213 glColor3f(1, 1, 1);
214
215 if (Texture)
216 glEnable(GL_TEXTURE_2D);
217
218 if (Arrays) {
219 glEnableClientState(GL_VERTEX_ARRAY);
220 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
221 glDrawElements(GL_QUADS, sizeof(vertex_index) / sizeof(vertex_index[0]),
222 GL_UNSIGNED_INT, vertex_index);
223 glDisableClientState(GL_VERTEX_ARRAY);
224 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
225 }
226 else {
227 /* Back */
228 glBegin(GL_QUADS);
229 glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH);
230 glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-DEPTH);
231 glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-DEPTH);
232 glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-DEPTH);
233 glEnd();
234
235 /* Floor */
236 glBegin(GL_QUADS);
237 glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH);
238 glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-DEPTH);
239 glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, DEPTH); glVertex3f( 1.0f,-1.0f,0.0);
240 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, DEPTH); glVertex3f(-1.0f,-1.0f,0.0);
241 glEnd();
242
243 /* Roof */
244 glBegin(GL_QUADS);
245 glFogCoordf_ext(DEPTH); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f,-DEPTH);
246 glFogCoordf_ext(DEPTH); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,-DEPTH);
247 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, DEPTH); glVertex3f( 1.0f, 1.0f,0.0);
248 glFogCoordf_ext(0.0f); glTexCoord2f(1.0f, DEPTH); glVertex3f(-1.0f, 1.0f,0.0);
249 glEnd();
250
251 /* Right */
252 glBegin(GL_QUADS);
253 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,-1.0f,0.0);
254 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f,0.0);
255 glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 0.0f); glVertex3f( 1.0f, 1.0f,-DEPTH);
256 glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 1.0f); glVertex3f( 1.0f,-1.0f,-DEPTH);
257 glEnd();
258
259 /* Left */
260 glBegin(GL_QUADS);
261 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,0.0);
262 glFogCoordf_ext(0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,0.0);
263 glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 1.0f); glVertex3f(-1.0f, 1.0f,-DEPTH);
264 glFogCoordf_ext(DEPTH); glTexCoord2f(DEPTH, 0.0f); glVertex3f(-1.0f,-1.0f,-DEPTH);
265 glEnd();
266 }
267
268 glDisable(GL_TEXTURE_2D);
269
270 PrintInfo();
271
272 glutSwapBuffers();
273 }
274
275
276 static void
277 Reshape( int width, int height )
278 {
279 glViewport(0, 0, width, height);
280 glMatrixMode(GL_PROJECTION);
281 glLoadIdentity();
282 glFrustum(-1, 1, -1, 1, 1.0, 100);
283 glMatrixMode(GL_MODELVIEW);
284 glLoadIdentity();
285 }
286
287
288 static void
289 Key( unsigned char key, int x, int y )
290 {
291 (void) x;
292 (void) y;
293 switch (key) {
294 case 'a':
295 Arrays = !Arrays;
296 break;
297 case 'f':
298 case 'm':
299 fogMode = SetFogMode(fogMode + 1);
300 break;
301 case 'D':
302 fogDensity += 0.05;
303 SetFogMode(fogMode);
304 break;
305 case 'd':
306 if (fogDensity > 0.0) {
307 fogDensity -= 0.05;
308 }
309 SetFogMode(fogMode);
310 break;
311 case 's':
312 if (fogStart > 0.0) {
313 fogStart -= 0.25;
314 }
315 SetFogMode(fogMode);
316 break;
317 case 'S':
318 if (fogStart < 100.0) {
319 fogStart += 0.25;
320 }
321 SetFogMode(fogMode);
322 break;
323 case 'e':
324 if (fogEnd > 0.0) {
325 fogEnd -= 0.25;
326 }
327 SetFogMode(fogMode);
328 break;
329 case 'E':
330 if (fogEnd < 100.0) {
331 fogEnd += 0.25;
332 }
333 SetFogMode(fogMode);
334 break;
335 case 'c':
336 fogCoord = SetFogCoord(fogCoord ^ GL_TRUE);
337 break;
338 case 't':
339 Texture = !Texture;
340 break;
341 case 'z':
342 camz -= 0.1;
343 break;
344 case 'Z':
345 camz += 0.1;
346 break;
347 case 'r':
348 Reset();
349 break;
350 case 27:
351 exit(0);
352 break;
353 }
354 glutPostRedisplay();
355 }
356
357
358 static void
359 Init(void)
360 {
361 static const GLubyte teximage[2][2][4] = {
362 { { 255, 255, 255, 255}, { 128, 128, 128, 255} },
363 { { 128, 128, 128, 255}, { 255, 255, 255, 255} }
364 };
365
366 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
367
368 if (!GLEW_EXT_fog_coord) {
369 printf("GL_EXT_fog_coord not supported!\n");
370 }
371
372 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0,
373 GL_RGBA, GL_UNSIGNED_BYTE, teximage);
374 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
376
377 glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
378
379 glDepthFunc(GL_LEQUAL);
380 glEnable(GL_DEPTH_TEST);
381 glShadeModel(GL_SMOOTH);
382 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
383
384 glFogfv(GL_FOG_COLOR, fogColor);
385 glHint(GL_FOG_HINT, GL_NICEST);
386 fogCoord = SetFogCoord(GL_TRUE); /* try to enable fog_coord */
387 fogMode = SetFogMode(1);
388
389 glEnableClientState(GL_VERTEX_ARRAY);
390 glVertexPointer(3, GL_FLOAT, 0, vertex_pointer);
391
392 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
393 glTexCoordPointer(2, GL_FLOAT, 0, texcoord_pointer);
394
395 if (GLEW_EXT_fog_coord) {
396 glEnableClientState(GL_FOG_COORDINATE_ARRAY_EXT);
397 glFogCoordPointerEXT(GL_FLOAT, 0, fogcoord_pointer);
398 }
399
400 Reset();
401 }
402
403
404 int
405 main( int argc, char *argv[] )
406 {
407 glutInitWindowSize( 600, 600 );
408 glutInit( &argc, argv );
409 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
410 glutCreateWindow(argv[0]);
411 glewInit();
412 glutReshapeFunc( Reshape );
413 glutKeyboardFunc( Key );
414 glutDisplayFunc( Display );
415 Init();
416 glutMainLoop();
417 return 0;
418 }