Merge branch 'mesa_7_7_branch'
[mesa.git] / progs / demos / texenv.c
1
2 /* Copyright (c) Mark J. Kilgard, 1994. */
3
4 /**
5 * (c) Copyright 1993, Silicon Graphics, Inc.
6 * ALL RIGHTS RESERVED
7 * Permission to use, copy, modify, and distribute this software for
8 * any purpose and without fee is hereby granted, provided that the above
9 * copyright notice appear in all copies and that both the copyright notice
10 * and this permission notice appear in supporting documentation, and that
11 * the name of Silicon Graphics, Inc. not be used in advertising
12 * or publicity pertaining to distribution of the software without specific,
13 * written prior permission.
14 *
15 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
16 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
18 * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
20 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
21 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
22 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
23 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
24 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
26 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
27 *
28 * US Government Users Restricted Rights
29 * Use, duplication, or disclosure by the Government is subject to
30 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
31 * (c)(1)(ii) of the Rights in Technical Data and Computer Software
32 * clause at DFARS 252.227-7013 and/or in similar or successor
33 * clauses in the FAR or the DOD or NASA FAR Supplement.
34 * Unpublished-- rights reserved under the copyright laws of the
35 * United States. Contractor/manufacturer is Silicon Graphics,
36 * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
37 *
38 * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
39 */
40
41 /*
42 * Demonstrates texture environment modes and internal image formats.
43 */
44
45 /*
46 * Hacked on, updated by Gareth Hughes <gareth@valinux.com>
47 */
48
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <GL/glut.h>
53
54 #undef max
55 #undef min
56 #define max( a, b ) ((a) >= (b) ? (a) : (b))
57 #define min( a, b ) ((a) <= (b) ? (a) : (b))
58
59 GLfloat lightCheck[4] = { 0.7, 0.7, 0.7, 1.0 };
60 GLfloat darkCheck[4] = { 0.3, 0.3, 0.3, 1.0 };
61
62 GLfloat labelColor0[4] = { 1.0, 1.0, 1.0, 1.0 };
63 GLfloat labelColor1[4] = { 1.0, 1.0, 0.4, 1.0 };
64 GLfloat *labelInfoColor = labelColor0;
65 GLfloat labelLevelColor0[4] = { 0.8, 0.8, 0.1, 1.0 };
66 GLfloat labelLevelColor1[4] = { 0.0, 0.0, 0.0, 1.0 };
67
68 GLboolean doubleBuffered = GL_TRUE;
69 GLboolean drawBackground = GL_FALSE;
70 GLboolean drawBlended = GL_TRUE;
71 GLboolean drawSmooth = GL_FALSE;
72 GLboolean drawTextured = GL_TRUE;
73 GLboolean displayLevelInfo = GL_FALSE;
74
75 int textureWidth = 64;
76 int textureHeight = 64;
77
78 int winWidth = 580, winHeight = 720;
79 static int Win;
80
81
82 struct formatInfo {
83 GLenum baseFormat;
84 GLenum internalFormat;
85 char *name;
86 };
87
88 #define NUM_LUMINANCE_FORMATS (sizeof(luminanceFormats) / sizeof(luminanceFormats[0]))
89 struct formatInfo luminanceFormats[] =
90 {
91 { GL_LUMINANCE, GL_LUMINANCE, "LUMINANCE" },
92 { GL_LUMINANCE, GL_LUMINANCE4, "LUMINANCE4" },
93 { GL_LUMINANCE, GL_LUMINANCE8, "LUMINANCE8" },
94 { GL_LUMINANCE, GL_LUMINANCE12, "LUMINANCE12" },
95 { GL_LUMINANCE, GL_LUMINANCE16, "LUMINANCE16" },
96 };
97
98 #define NUM_ALPHA_FORMATS (sizeof(alphaFormats) / sizeof(alphaFormats[0]))
99 struct formatInfo alphaFormats[] =
100 {
101 { GL_ALPHA, GL_ALPHA, "ALPHA" },
102 { GL_ALPHA, GL_ALPHA4, "ALPHA4" },
103 { GL_ALPHA, GL_ALPHA8, "ALPHA8" },
104 { GL_ALPHA, GL_ALPHA12, "ALPHA12" },
105 { GL_ALPHA, GL_ALPHA16, "ALPHA16" },
106 };
107
108 #define NUM_INTENSITY_FORMATS (sizeof(intensityFormats) / sizeof(intensityFormats[0]))
109 struct formatInfo intensityFormats[] =
110 {
111 { GL_INTENSITY, GL_INTENSITY, "INTENSITY" },
112 { GL_INTENSITY, GL_INTENSITY4, "INTENSITY4" },
113 { GL_INTENSITY, GL_INTENSITY8, "INTENSITY8" },
114 { GL_INTENSITY, GL_INTENSITY12, "INTENSITY12" },
115 { GL_INTENSITY, GL_INTENSITY16, "INTENSITY16" },
116 };
117
118 #define NUM_LUMINANCE_ALPHA_FORMATS (sizeof(luminanceAlphaFormats) / sizeof(luminanceAlphaFormats[0]))
119 struct formatInfo luminanceAlphaFormats[] =
120 {
121 { GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, "LUMINANCE_ALPHA" },
122 { GL_LUMINANCE_ALPHA, GL_LUMINANCE4_ALPHA4, "LUMINANCE4_ALPHA4" },
123 { GL_LUMINANCE_ALPHA, GL_LUMINANCE6_ALPHA2, "LUMINANCE6_ALPHA2" },
124 { GL_LUMINANCE_ALPHA, GL_LUMINANCE8_ALPHA8, "LUMINANCE8_ALPHA8" },
125 { GL_LUMINANCE_ALPHA, GL_LUMINANCE12_ALPHA4, "LUMINANCE12_ALPHA4" },
126 { GL_LUMINANCE_ALPHA, GL_LUMINANCE12_ALPHA12, "LUMINANCE12_ALPHA12" },
127 { GL_LUMINANCE_ALPHA, GL_LUMINANCE16_ALPHA16, "LUMINANCE16_ALPHA16" },
128 };
129
130 #define NUM_RGB_FORMATS (sizeof(rgbFormats) / sizeof(rgbFormats[0]))
131 struct formatInfo rgbFormats[] =
132 {
133 { GL_RGB, GL_RGB, "RGB" },
134 { GL_RGB, GL_R3_G3_B2, "R3_G3_B2" },
135 { GL_RGB, GL_RGB4, "RGB4" },
136 { GL_RGB, GL_RGB5, "RGB5" },
137 { GL_RGB, GL_RGB8, "RGB8" },
138 { GL_RGB, GL_RGB10, "RGB10" },
139 { GL_RGB, GL_RGB12, "RGB12" },
140 { GL_RGB, GL_RGB16, "RGB16" },
141 };
142
143 #define NUM_RGBA_FORMATS (sizeof(rgbaFormats) / sizeof(rgbaFormats[0]))
144 struct formatInfo rgbaFormats[] =
145 {
146 { GL_RGBA, GL_RGBA, "RGBA" },
147 { GL_RGBA, GL_RGBA2, "RGBA2" },
148 { GL_RGBA, GL_RGBA4, "RGBA4" },
149 { GL_RGBA, GL_RGB5_A1, "RGB5_A1" },
150 { GL_RGBA, GL_RGBA8, "RGBA8" },
151 { GL_RGBA, GL_RGB10_A2, "RGB10_A2" },
152 { GL_RGBA, GL_RGBA12, "RGBA12" },
153 { GL_RGBA, GL_RGBA16, "RGBA16" },
154 };
155
156 struct baseFormatInfo {
157 struct formatInfo *format;
158 int current, number;
159 };
160
161 #define NUM_BASE_FORMATS (sizeof(baseFormats) / sizeof(baseFormats[0]))
162 int baseFormat;
163 struct baseFormatInfo baseFormats[] =
164 {
165 { luminanceFormats, 0, NUM_LUMINANCE_FORMATS },
166 { alphaFormats, 0, NUM_ALPHA_FORMATS },
167 { intensityFormats, 0, NUM_INTENSITY_FORMATS },
168 { luminanceAlphaFormats, 0, NUM_LUMINANCE_ALPHA_FORMATS },
169 { rgbFormats, 0, NUM_RGB_FORMATS },
170 { rgbaFormats, 0, NUM_RGBA_FORMATS },
171 };
172
173 #define NUM_ENV_COLORS (sizeof(envColors) / sizeof(envColors[0]))
174 int envColor = 0;
175 GLfloat envColors[][4] =
176 {
177 { 0.0, 0.0, 0.0, 1.0 },
178 { 1.0, 0.0, 0.0, 1.0 },
179 { 0.0, 1.0, 0.0, 1.0 },
180 { 0.0, 0.0, 1.0, 1.0 },
181 { 1.0, 1.0, 1.0, 1.0 },
182 };
183
184 struct envModeInfo {
185 GLenum mode;
186 char *name;
187 };
188
189 /* allow for run-time check for GL_EXT_texture_env_add */
190 int NUM_ENV_MODES = 5;
191 struct envModeInfo envModes[] =
192 {
193 { GL_REPLACE, "REPLACE" },
194 { GL_MODULATE, "MODULATE" },
195 { GL_BLEND, "BLEND" },
196 { GL_DECAL, "DECAL" },
197 #if GL_EXT_texture_env_add
198 { GL_ADD, "ADD" },
199 #endif
200 };
201
202 static void checkErrors( void )
203 {
204 GLenum error;
205
206 while ( (error = glGetError()) != GL_NO_ERROR ) {
207 fprintf( stderr, "Error: %s\n", (char *) gluErrorString( error ) );
208 }
209 }
210
211 static void drawString( const char *string, GLfloat x, GLfloat y,
212 const GLfloat color[4] )
213 {
214 glColor4fv( color );
215 glRasterPos2f( x, y );
216
217 while ( *string ) {
218 glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_10, *string );
219 string++;
220 }
221 }
222
223 static void drawStringOutline( const char *string, GLfloat x, GLfloat y,
224 const GLfloat color[4],
225 const GLfloat outline[4] )
226 {
227 drawString( string, x - 1, y, outline );
228 drawString( string, x + 1, y, outline );
229 drawString( string, x, y - 1, outline );
230 drawString( string, x, y + 1, outline );
231 drawString( string, x, y, color );
232 }
233
234 static void begin2D( int width, int height )
235 {
236 glMatrixMode( GL_PROJECTION );
237
238 glPushMatrix();
239 glLoadIdentity();
240
241 glOrtho( 0, width, 0, height, -1, 1 );
242 glMatrixMode( GL_MODELVIEW );
243
244 glPushMatrix();
245 glLoadIdentity();
246 }
247
248 static void end2D( void )
249 {
250 glMatrixMode( GL_PROJECTION );
251 glPopMatrix();
252 glMatrixMode( GL_MODELVIEW );
253 glPopMatrix();
254 }
255
256 static void initialize( void )
257 {
258 glMatrixMode( GL_PROJECTION );
259 glLoadIdentity();
260
261 glOrtho( -1.5, 1.5, -1.5, 1.5, -1.5, 1.5 );
262
263 glMatrixMode(GL_MODELVIEW);
264 glLoadIdentity();
265
266 glShadeModel( GL_FLAT );
267 }
268
269 /* ARGSUSED1 */
270 static void keyboard( unsigned char c, int x, int y )
271 {
272 switch ( c ) {
273 case 'c':
274 envColor++;
275 envColor = envColor % (int) NUM_ENV_COLORS;
276 break;
277 case 'g':
278 drawBackground = !drawBackground;
279 break;
280 case 'b':
281 drawBlended = !drawBlended;
282 break;
283 case 's':
284 drawSmooth = !drawSmooth;
285 break;
286 case 't':
287 drawTextured = !drawTextured;
288 break;
289 case 'i':
290 displayLevelInfo = !displayLevelInfo;
291 break;
292 case 27: /* Escape key should force exit. */
293 glutDestroyWindow(Win);
294 exit(0);
295 break;
296 default:
297 break;
298 }
299 glutPostRedisplay();
300 }
301
302 /* ARGSUSED1 */
303 static void special( int key, int x, int y )
304 {
305 switch ( key ) {
306 case GLUT_KEY_DOWN:
307 if ( ++baseFormat > NUM_BASE_FORMATS - 1 ) {
308 baseFormat = 0;
309 }
310 break;
311 case GLUT_KEY_UP:
312 if ( --baseFormat < 0 ) {
313 baseFormat = NUM_BASE_FORMATS - 1;
314 }
315 break;
316 case GLUT_KEY_LEFT:
317 --baseFormats[baseFormat].current;
318 if ( baseFormats[baseFormat].current < 0 ) {
319 baseFormats[baseFormat].current = baseFormats[baseFormat].number - 1;
320 }
321 break;
322 case GLUT_KEY_RIGHT:
323 ++baseFormats[baseFormat].current;
324 if ( baseFormats[baseFormat].current > baseFormats[baseFormat].number - 1 ) {
325 baseFormats[baseFormat].current = 0;
326 }
327 break;
328 default:
329 break;
330 }
331 glutPostRedisplay();
332 }
333
334 static void
335 reshape( int w, int h )
336 {
337 winWidth = w;
338 winHeight = h;
339 /* No need to call glViewPort here since "draw" calls it! */
340 }
341
342 static void loadTexture( int width, int height,
343 const struct formatInfo *format )
344 {
345 int luminanceSize = 0;
346 int alphaSize = 0;
347 int rgbSize = 0;
348 GLenum textureFormat;
349 GLubyte *texImage, *p;
350 int elementsPerGroup, elementSize, groupSize, rowSize;
351 int i, j;
352
353 switch ( format->baseFormat ) {
354 case GL_LUMINANCE:
355 luminanceSize = 1;
356 textureFormat = GL_LUMINANCE;
357 break;
358 case GL_INTENSITY:
359 luminanceSize = 1;
360 /* Note: format=GL_INTENSITY for glTexImage is not legal */
361 textureFormat = GL_LUMINANCE;
362 break;
363 case GL_ALPHA:
364 alphaSize = 1;
365 textureFormat = GL_ALPHA;
366 break;
367 case GL_LUMINANCE_ALPHA:
368 luminanceSize = 1;
369 alphaSize = 1;
370 textureFormat = GL_LUMINANCE_ALPHA;
371 break;
372 case GL_RGB:
373 rgbSize = 3;
374 textureFormat = GL_RGB;
375 break;
376 case GL_RGBA:
377 rgbSize = 3;
378 alphaSize = 1;
379 textureFormat = GL_RGBA;
380 break;
381 default:
382 fprintf(stderr, "bad internal format info\n");
383 return;
384 }
385
386 elementsPerGroup = luminanceSize + alphaSize + rgbSize;
387 elementSize = sizeof(GLubyte);
388 groupSize = elementsPerGroup * elementSize;
389 rowSize = width * groupSize;
390
391 if ( (texImage = (GLubyte *) malloc( height * rowSize ) ) == NULL ) {
392 fprintf( stderr, "texture malloc failed\n" );
393 return;
394 }
395
396 for ( i = 0 ; i < height ; i++ )
397 {
398 p = texImage + i * rowSize;
399
400 for ( j = 0 ; j < width ; j++ )
401 {
402 if ( luminanceSize > 0 )
403 {
404 /**
405 ** +-----+-----+
406 ** | | |
407 ** | W | LG |
408 ** | | |
409 ** +-----+-----+
410 ** | | |
411 ** | DG | B |
412 ** | | |
413 ** +-----+-----+
414 **/
415 if ( i > height / 2 ) {
416 if ( j < width / 2 ) {
417 p[0] = 0xff;
418 } else {
419 p[0] = 0xaa;
420 }
421 } else {
422 if ( j < width / 2 ) {
423 p[0] = 0x55;
424 } else {
425 p[0] = 0x00;
426 }
427 }
428 p += elementSize;
429 }
430
431 if ( rgbSize > 0 )
432 {
433 /**
434 ** +-----+-----+
435 ** | | |
436 ** | R | G |
437 ** | | |
438 ** +-----+-----+
439 ** | | |
440 ** | Y | B |
441 ** | | |
442 ** +-----+-----+
443 **/
444 if ( i > height / 2 ) {
445 if ( j < width / 2 ) {
446 p[0] = 0xff;
447 p[1] = 0x00;
448 p[2] = 0x00;
449 } else {
450 p[0] = 0x00;
451 p[1] = 0xff;
452 p[2] = 0x00;
453 }
454 } else {
455 if ( j < width / 2 ) {
456 p[0] = 0xff;
457 p[1] = 0xff;
458 p[2] = 0x00;
459 } else {
460 p[0] = 0x00;
461 p[1] = 0x00;
462 p[2] = 0xff;
463 }
464 }
465 p += 3 * elementSize;
466 }
467
468 if ( alphaSize > 0 )
469 {
470 /**
471 ** +-----------+
472 ** | W |
473 ** | +-----+ |
474 ** | | | |
475 ** | | B | |
476 ** | | | |
477 ** | +-----+ |
478 ** | |
479 ** +-----------+
480 **/
481 int i2 = i - height / 2;
482 int j2 = j - width / 2;
483 int h8 = height / 8;
484 int w8 = width / 8;
485 if ( -h8 <= i2 && i2 <= h8 && -w8 <= j2 && j2 <= w8 ) {
486 p[0] = 0x00;
487 } else if ( -2 * h8 <= i2 && i2 <= 2 * h8 && -2 * w8 <= j2 && j2 <= 2 * w8 ) {
488 p[0] = 0x55;
489 } else if ( -3 * h8 <= i2 && i2 <= 3 * h8 && -3 * w8 <= j2 && j2 <= 3 * w8 ) {
490 p[0] = 0xaa;
491 } else {
492 p[0] = 0xff;
493 }
494 p += elementSize;
495 }
496 }
497 }
498
499 glTexImage2D( GL_TEXTURE_2D, 0,
500 format->internalFormat, width, height, 0,
501 textureFormat, GL_UNSIGNED_BYTE, texImage );
502
503 free( texImage );
504 }
505
506 static void drawCheck( int w, int h, const GLfloat lightCheck[4],
507 const GLfloat darkCheck[4] )
508 {
509 float dw = 2.0 / w;
510 float dh = 2.0 / h;
511 int i, j;
512
513 for ( i = 0 ; i < w ; i++ ) {
514 GLfloat x0 = -1.0 + i * dw;
515 GLfloat x1 = x0 + dw;
516
517 glBegin( GL_QUAD_STRIP );
518
519 for ( j = 0 ; j <= h ; j++ ) {
520 GLfloat y = -1.0 + j * dh;
521
522 if ( (i ^ j) & 1 ) {
523 glColor4fv( lightCheck );
524 } else {
525 glColor4fv( darkCheck );
526 }
527
528 glVertex2f( x0, y );
529 glVertex2f( x1, y );
530 }
531
532 glEnd();
533 }
534 }
535
536 static const char *lookupFormat( GLint format )
537 {
538 switch ( format ) {
539 case GL_RGBA:
540 return "GL_RGBA";
541 case GL_RGB:
542 return "GL_RGB";
543 case GL_ALPHA:
544 return "GL_ALPHA";
545 case GL_LUMINANCE:
546 return "GL_LUMINANCE";
547 case GL_LUMINANCE_ALPHA:
548 return "GL_LUMINANCE_ALPHA";
549 case GL_INTENSITY:
550 return "GL_INTENSITY";
551 case GL_COLOR_INDEX:
552 return "GL_COLOR_INDEX";
553 case GL_BGRA:
554 return "GL_BGRA";
555 case GL_BGR:
556 return "GL_BGR";
557 default:
558 return "unknown format";
559 }
560 }
561
562 static void drawSample( int x, int y, int w, int h,
563 const struct formatInfo *format,
564 const struct envModeInfo *envMode )
565 {
566 glViewport( x, y, w, h );
567 glScissor( x, y, w, h );
568
569 glClearColor( 0.1, 0.1, 0.1, 1.0 );
570 glClear( GL_COLOR_BUFFER_BIT );
571
572 begin2D( w, h );
573 drawString( format->name, 10, h - 15, labelInfoColor );
574 drawString( envMode->name, 10, 5, labelInfoColor );
575 end2D();
576
577 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, envMode->mode );
578 glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColors[envColor] );
579
580 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
581 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
582
583 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
584 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
585
586 loadTexture( textureWidth, textureHeight, format );
587
588 if ( drawBackground ) {
589 drawCheck( 15, 15, lightCheck, darkCheck );
590 }
591 if ( drawBlended ) {
592 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
593 glEnable( GL_BLEND );
594 }
595 if ( drawSmooth ) {
596 glShadeModel( GL_SMOOTH );
597 }
598 else {
599 glShadeModel( GL_FLAT );
600 glColor4f(1, 1, 1, 1);
601 }
602 if ( drawTextured ) {
603 glEnable( GL_TEXTURE_2D );
604 }
605
606 /*
607 * if (drawSmooth) then draw quad which goes from purple at the
608 * bottom (100% alpha) to green at the top (50% alpha).
609 */
610 glBegin( GL_QUADS );
611 if ( drawSmooth ) glColor4f( 1.0, 0.0, 1.0, 1.0 );
612 glTexCoord2f( 0.0, 0.0 );
613 glVertex2f( -0.8, -0.8 );
614
615 if ( drawSmooth ) glColor4f( 1.0, 0.0, 1.0, 1.0 );
616 glTexCoord2f( 1.0, 0.0 );
617 glVertex2f( 0.8, -0.8 );
618
619 if ( drawSmooth ) glColor4f( 0.0, 1.0, 0.0, 0.5 );
620 glTexCoord2f( 1.0, 1.0 );
621 glVertex2f( 0.8, 0.8 );
622
623 if ( drawSmooth ) glColor4f( 0.0, 1.0, 0.0, 0.5 );
624 glTexCoord2f( 0.0, 1.0 );
625 glVertex2f( -0.8, 0.8 );
626 glEnd();
627
628 glDisable( GL_BLEND );
629 glShadeModel( GL_FLAT );
630 glDisable( GL_TEXTURE_2D );
631
632 if ( envMode->mode == GL_DECAL &&
633 (format->baseFormat == GL_ALPHA ||
634 format->baseFormat == GL_LUMINANCE ||
635 format->baseFormat == GL_LUMINANCE_ALPHA ||
636 format->baseFormat == GL_INTENSITY)) {
637 /* undefined format/mode combination */
638 begin2D( w, h );
639 drawStringOutline( "UNDEFINED MODE", 15, h / 2,
640 labelLevelColor0, labelLevelColor1 );
641 end2D();
642 }
643 else if ( displayLevelInfo ) {
644 GLint width, height, border, format;
645 GLint redSize, greenSize, blueSize, alphaSize;
646 GLint luminanceSize, intensitySize;
647 char buf[255];
648
649 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width );
650 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height );
651 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border );
652 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format );
653 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &redSize );
654 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &greenSize );
655 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &blueSize );
656 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alphaSize );
657 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &luminanceSize );
658 glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &intensitySize );
659
660 begin2D( w, h );
661 sprintf( buf, "dimensions: %d x %d", width, height );
662 drawStringOutline( buf, 15, h / 2 + 20, labelLevelColor0, labelLevelColor1 );
663
664 sprintf( buf, "border: %d", border );
665 drawStringOutline( buf, 15, h / 2 + 10, labelLevelColor0, labelLevelColor1 );
666
667 sprintf( buf, "internal format:" );
668 drawStringOutline( buf, 15, h / 2, labelLevelColor0, labelLevelColor1 );
669
670 sprintf( buf, " %s", lookupFormat( format ) );
671 drawStringOutline( buf, 15, h / 2 - 10, labelLevelColor0, labelLevelColor1 );
672
673 sprintf( buf, "sizes:" );
674 drawStringOutline( buf, 15, h / 2 - 20, labelLevelColor0, labelLevelColor1 );
675
676 sprintf( buf, " %d / %d / %d / %d / %d / %d",
677 redSize, greenSize, blueSize, alphaSize,
678 luminanceSize, intensitySize );
679 drawStringOutline( buf, 15, h / 2 - 30, labelLevelColor0, labelLevelColor1 );
680
681 end2D();
682 }
683 }
684
685 static void display( void )
686 {
687 int numX = NUM_ENV_MODES, numY = NUM_BASE_FORMATS;
688 float xBase = (float) winWidth * 0.01;
689 float xOffset = (winWidth - xBase) / numX;
690 float xSize = max( xOffset - xBase, 1 );
691 float yBase = (float) winHeight * 0.01;
692 float yOffset = (winHeight - yBase) / numY;
693 float ySize = max( yOffset - yBase, 1 );
694 float x, y;
695 int i, j;
696
697 glViewport( 0, 0, winWidth, winHeight );
698 glDisable( GL_SCISSOR_TEST );
699 glClearColor( 0.0, 0.0, 0.0, 0.0 );
700 glClear( GL_COLOR_BUFFER_BIT );
701 glEnable( GL_SCISSOR_TEST );
702
703 x = xBase;
704 y = (winHeight - 1) - yOffset;
705
706 for ( i = 0 ; i < NUM_BASE_FORMATS ; i++ )
707 {
708 struct formatInfo *format;
709
710 if ( i == baseFormat ) {
711 labelInfoColor = labelColor1;
712 } else {
713 labelInfoColor = labelColor0;
714 }
715
716 format = &baseFormats[i].format[baseFormats[i].current];
717
718 for ( j = 0 ; j < NUM_ENV_MODES ; j++ ) {
719 struct envModeInfo *envMode;
720
721 envMode = &envModes[j];
722 drawSample( x, y, xSize, ySize, format, envMode );
723 x += xOffset;
724 }
725
726 x = xBase;
727 y -= yOffset;
728 }
729
730 if ( doubleBuffered ) {
731 glutSwapBuffers();
732 } else {
733 glFlush();
734 }
735
736 checkErrors();
737 }
738
739 static void usage( char *name )
740 {
741 fprintf( stderr, "usage: %s [ options ]\n", name );
742 fprintf( stderr, "\n" );
743 fprintf( stderr, "options:\n" );
744 fprintf( stderr, " -sb single buffered\n" );
745 fprintf( stderr, " -db double buffered\n" );
746 fprintf( stderr, " -info print OpenGL driver info\n" );
747 }
748
749 static void instructions( void )
750 {
751 fprintf( stderr, "texenv - texture environment and internal format test\n" );
752 fprintf( stderr, "\n" );
753 fprintf( stderr, " [c] - cycle through background colors\n" );
754 fprintf( stderr, " [g] - toggle background\n" );
755 fprintf( stderr, " [b] - toggle blend\n" );
756 fprintf( stderr, " [s] - toggle smooth shading\n" );
757 fprintf( stderr, " [t] - toggle texturing\n" );
758 fprintf( stderr, " [i] - toggle information display\n" );
759 fprintf( stderr, " up/down - select row\n" );
760 fprintf( stderr, " left/right - change row's internal format\n" );
761 }
762
763 int main( int argc, char *argv[] )
764 {
765 GLboolean info = GL_FALSE;
766 int i;
767
768 glutInitWindowSize( winWidth, winHeight );
769 glutInit( &argc, argv );
770
771 for ( i = 1 ; i < argc ; i++ ) {
772 if ( !strcmp( "-sb", argv[i] ) ) {
773 doubleBuffered = GL_FALSE;
774 } else if ( !strcmp( "-db", argv[i] ) ) {
775 doubleBuffered = GL_TRUE;
776 } else if ( !strcmp( "-info", argv[i] ) ) {
777 info = GL_TRUE;
778 } else {
779 usage( argv[0] );
780 exit( 1 );
781 }
782 }
783
784 if ( doubleBuffered ) {
785 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
786 } else {
787 glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );
788 }
789
790 Win = glutCreateWindow( "Texture Environment Test" );
791
792 initialize();
793 instructions();
794
795 if ( info ) {
796 printf( "\n" );
797 printf( "GL_RENDERER = %s\n", (char *) glGetString( GL_RENDERER ) );
798 printf( "GL_VERSION = %s\n", (char *) glGetString( GL_VERSION ) );
799 printf( "GL_VENDOR = %s\n", (char *) glGetString( GL_VENDOR ) ) ;
800 printf( "GL_EXTENSIONS = %s\n", (char *) glGetString( GL_EXTENSIONS ) );
801 }
802
803 #if GL_EXT_texture_env_add
804 if ( !glutExtensionSupported( "GL_EXT_texture_env_add" ) ) {
805 fprintf( stderr, "missing extension: GL_EXT_texture_env_add\n" );
806 NUM_ENV_MODES--;
807 }
808 #endif
809
810 glutDisplayFunc( display );
811 glutReshapeFunc( reshape );
812 glutKeyboardFunc( keyboard );
813 glutSpecialFunc( special );
814 glutMainLoop();
815
816 return 0;
817 }