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