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