132001f49Smrg
232001f49Smrg/* Copyright (c) Mark J. Kilgard, 1994. */
332001f49Smrg
432001f49Smrg/**
532001f49Smrg * (c) Copyright 1993, Silicon Graphics, Inc.
632001f49Smrg * ALL RIGHTS RESERVED
732001f49Smrg * Permission to use, copy, modify, and distribute this software for
832001f49Smrg * any purpose and without fee is hereby granted, provided that the above
932001f49Smrg * copyright notice appear in all copies and that both the copyright notice
1032001f49Smrg * and this permission notice appear in supporting documentation, and that
1132001f49Smrg * the name of Silicon Graphics, Inc. not be used in advertising
1232001f49Smrg * or publicity pertaining to distribution of the software without specific,
1332001f49Smrg * written prior permission.
1432001f49Smrg *
1532001f49Smrg * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
1632001f49Smrg * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
1732001f49Smrg * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
1832001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
1932001f49Smrg * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
2032001f49Smrg * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
2132001f49Smrg * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
2232001f49Smrg * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
2332001f49Smrg * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
2432001f49Smrg * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
2532001f49Smrg * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
2632001f49Smrg * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
2732001f49Smrg *
2832001f49Smrg * US Government Users Restricted Rights
2932001f49Smrg * Use, duplication, or disclosure by the Government is subject to
3032001f49Smrg * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
3132001f49Smrg * (c)(1)(ii) of the Rights in Technical Data and Computer Software
3232001f49Smrg * clause at DFARS 252.227-7013 and/or in similar or successor
3332001f49Smrg * clauses in the FAR or the DOD or NASA FAR Supplement.
3432001f49Smrg * Unpublished-- rights reserved under the copyright laws of the
3532001f49Smrg * United States.  Contractor/manufacturer is Silicon Graphics,
3632001f49Smrg * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
3732001f49Smrg *
3832001f49Smrg * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
3932001f49Smrg */
4032001f49Smrg
4132001f49Smrg/*
4232001f49Smrg * Demonstrates texture environment modes and internal image formats.
4332001f49Smrg */
4432001f49Smrg
4532001f49Smrg/*
4632001f49Smrg * Hacked on, updated by Gareth Hughes <gareth@valinux.com>
4732001f49Smrg */
4832001f49Smrg
4932001f49Smrg#include <stdio.h>
5032001f49Smrg#include <stdlib.h>
5132001f49Smrg#include <string.h>
5232001f49Smrg#include <GL/glew.h> /* for GL_BGRA */
5332001f49Smrg#include "glut_wrap.h"
5432001f49Smrg
5532001f49Smrg#undef max
5632001f49Smrg#undef min
5732001f49Smrg#define max( a, b )	((a) >= (b) ? (a) : (b))
5832001f49Smrg#define min( a, b )	((a) <= (b) ? (a) : (b))
5932001f49Smrg
6032001f49SmrgGLfloat lightCheck[4] = { 0.7, 0.7, 0.7, 1.0 };
6132001f49SmrgGLfloat darkCheck[4] = { 0.3, 0.3, 0.3, 1.0 };
6232001f49Smrg
6332001f49SmrgGLfloat labelColor0[4] = { 1.0, 1.0, 1.0, 1.0 };
6432001f49SmrgGLfloat labelColor1[4] = { 1.0, 1.0, 0.4, 1.0 };
6532001f49SmrgGLfloat *labelInfoColor = labelColor0;
6632001f49SmrgGLfloat labelLevelColor0[4] = { 0.8, 0.8, 0.1, 1.0 };
6732001f49SmrgGLfloat labelLevelColor1[4] = { 0.0, 0.0, 0.0, 1.0 };
6832001f49Smrg
6932001f49SmrgGLboolean doubleBuffered = GL_TRUE;
7032001f49SmrgGLboolean drawBackground = GL_FALSE;
7132001f49SmrgGLboolean drawBlended = GL_TRUE;
7232001f49SmrgGLboolean drawSmooth = GL_FALSE;
7332001f49SmrgGLboolean drawTextured = GL_TRUE;
7432001f49SmrgGLboolean displayLevelInfo = GL_FALSE;
7532001f49Smrg
7632001f49Smrgint textureWidth = 64;
7732001f49Smrgint textureHeight = 64;
7832001f49Smrg
7932001f49Smrgint winWidth = 580, winHeight = 720;
8032001f49Smrgstatic int Win;
8132001f49Smrg
8232001f49Smrg
8332001f49Smrgstruct formatInfo {
8432001f49Smrg   GLenum	baseFormat;
8532001f49Smrg   GLenum	internalFormat;
8632001f49Smrg   char		*name;
8732001f49Smrg};
8832001f49Smrg
8932001f49Smrg#define NUM_LUMINANCE_FORMATS	(sizeof(luminanceFormats) / sizeof(luminanceFormats[0]))
9032001f49Smrgstruct formatInfo luminanceFormats[] =
9132001f49Smrg{
9232001f49Smrg   { GL_LUMINANCE, GL_LUMINANCE, "LUMINANCE" },
9332001f49Smrg   { GL_LUMINANCE, GL_LUMINANCE4, "LUMINANCE4" },
9432001f49Smrg   { GL_LUMINANCE, GL_LUMINANCE8, "LUMINANCE8" },
9532001f49Smrg   { GL_LUMINANCE, GL_LUMINANCE12, "LUMINANCE12" },
9632001f49Smrg   { GL_LUMINANCE, GL_LUMINANCE16, "LUMINANCE16" },
9732001f49Smrg};
9832001f49Smrg
9932001f49Smrg#define NUM_ALPHA_FORMATS	(sizeof(alphaFormats) / sizeof(alphaFormats[0]))
10032001f49Smrgstruct formatInfo alphaFormats[] =
10132001f49Smrg{
10232001f49Smrg   { GL_ALPHA, GL_ALPHA, "ALPHA" },
10332001f49Smrg   { GL_ALPHA, GL_ALPHA4, "ALPHA4" },
10432001f49Smrg   { GL_ALPHA, GL_ALPHA8, "ALPHA8" },
10532001f49Smrg   { GL_ALPHA, GL_ALPHA12, "ALPHA12" },
10632001f49Smrg   { GL_ALPHA, GL_ALPHA16, "ALPHA16" },
10732001f49Smrg};
10832001f49Smrg
10932001f49Smrg#define NUM_INTENSITY_FORMATS	(sizeof(intensityFormats) / sizeof(intensityFormats[0]))
11032001f49Smrgstruct formatInfo intensityFormats[] =
11132001f49Smrg{
11232001f49Smrg   { GL_INTENSITY, GL_INTENSITY, "INTENSITY" },
11332001f49Smrg   { GL_INTENSITY, GL_INTENSITY4, "INTENSITY4" },
11432001f49Smrg   { GL_INTENSITY, GL_INTENSITY8, "INTENSITY8" },
11532001f49Smrg   { GL_INTENSITY, GL_INTENSITY12, "INTENSITY12" },
11632001f49Smrg   { GL_INTENSITY, GL_INTENSITY16, "INTENSITY16" },
11732001f49Smrg};
11832001f49Smrg
11932001f49Smrg#define NUM_LUMINANCE_ALPHA_FORMATS	(sizeof(luminanceAlphaFormats) / sizeof(luminanceAlphaFormats[0]))
12032001f49Smrgstruct formatInfo luminanceAlphaFormats[] =
12132001f49Smrg{
12232001f49Smrg   { GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, "LUMINANCE_ALPHA" },
12332001f49Smrg   { GL_LUMINANCE_ALPHA, GL_LUMINANCE4_ALPHA4, "LUMINANCE4_ALPHA4" },
12432001f49Smrg   { GL_LUMINANCE_ALPHA, GL_LUMINANCE6_ALPHA2, "LUMINANCE6_ALPHA2" },
12532001f49Smrg   { GL_LUMINANCE_ALPHA, GL_LUMINANCE8_ALPHA8, "LUMINANCE8_ALPHA8" },
12632001f49Smrg   { GL_LUMINANCE_ALPHA, GL_LUMINANCE12_ALPHA4, "LUMINANCE12_ALPHA4" },
12732001f49Smrg   { GL_LUMINANCE_ALPHA, GL_LUMINANCE12_ALPHA12, "LUMINANCE12_ALPHA12" },
12832001f49Smrg   { GL_LUMINANCE_ALPHA, GL_LUMINANCE16_ALPHA16, "LUMINANCE16_ALPHA16" },
12932001f49Smrg};
13032001f49Smrg
13132001f49Smrg#define NUM_RGB_FORMATS		(sizeof(rgbFormats) / sizeof(rgbFormats[0]))
13232001f49Smrgstruct formatInfo rgbFormats[] =
13332001f49Smrg{
13432001f49Smrg   { GL_RGB, GL_RGB, "RGB" },
13532001f49Smrg   { GL_RGB, GL_R3_G3_B2, "R3_G3_B2" },
13632001f49Smrg   { GL_RGB, GL_RGB4, "RGB4" },
13732001f49Smrg   { GL_RGB, GL_RGB5, "RGB5" },
13832001f49Smrg   { GL_RGB, GL_RGB8, "RGB8" },
13932001f49Smrg   { GL_RGB, GL_RGB10, "RGB10" },
14032001f49Smrg   { GL_RGB, GL_RGB12, "RGB12" },
14132001f49Smrg   { GL_RGB, GL_RGB16, "RGB16" },
14232001f49Smrg};
14332001f49Smrg
14432001f49Smrg#define NUM_RGBA_FORMATS	(sizeof(rgbaFormats) / sizeof(rgbaFormats[0]))
14532001f49Smrgstruct formatInfo rgbaFormats[] =
14632001f49Smrg{
14732001f49Smrg   { GL_RGBA, GL_RGBA, "RGBA" },
14832001f49Smrg   { GL_RGBA, GL_RGBA2, "RGBA2" },
14932001f49Smrg   { GL_RGBA, GL_RGBA4, "RGBA4" },
15032001f49Smrg   { GL_RGBA, GL_RGB5_A1, "RGB5_A1" },
15132001f49Smrg   { GL_RGBA, GL_RGBA8, "RGBA8" },
15232001f49Smrg   { GL_RGBA, GL_RGB10_A2, "RGB10_A2" },
15332001f49Smrg   { GL_RGBA, GL_RGBA12, "RGBA12" },
15432001f49Smrg   { GL_RGBA, GL_RGBA16, "RGBA16" },
15532001f49Smrg};
15632001f49Smrg
15732001f49Smrgstruct baseFormatInfo {
15832001f49Smrg   struct	formatInfo *format;
15932001f49Smrg   int		current, number;
16032001f49Smrg};
16132001f49Smrg
16232001f49Smrg#define NUM_BASE_FORMATS	(sizeof(baseFormats) / sizeof(baseFormats[0]))
16332001f49Smrgint baseFormat;
16432001f49Smrgstruct baseFormatInfo baseFormats[] =
16532001f49Smrg{
16632001f49Smrg   { luminanceFormats, 0, NUM_LUMINANCE_FORMATS },
16732001f49Smrg   { alphaFormats, 0, NUM_ALPHA_FORMATS },
16832001f49Smrg   { intensityFormats, 0, NUM_INTENSITY_FORMATS },
16932001f49Smrg   { luminanceAlphaFormats, 0, NUM_LUMINANCE_ALPHA_FORMATS },
17032001f49Smrg   { rgbFormats, 0, NUM_RGB_FORMATS },
17132001f49Smrg   { rgbaFormats, 0, NUM_RGBA_FORMATS },
17232001f49Smrg};
17332001f49Smrg
17432001f49Smrg#define NUM_ENV_COLORS		(sizeof(envColors) / sizeof(envColors[0]))
17532001f49Smrgint envColor = 0;
17632001f49SmrgGLfloat envColors[][4] =
17732001f49Smrg{
17832001f49Smrg   { 0.0, 0.0, 0.0, 1.0 },
17932001f49Smrg   { 1.0, 0.0, 0.0, 1.0 },
18032001f49Smrg   { 0.0, 1.0, 0.0, 1.0 },
18132001f49Smrg   { 0.0, 0.0, 1.0, 1.0 },
18232001f49Smrg   { 1.0, 1.0, 1.0, 1.0 },
18332001f49Smrg};
18432001f49Smrg
18532001f49Smrgstruct envModeInfo {
18632001f49Smrg   GLenum	mode;
18732001f49Smrg   char		*name;
18832001f49Smrg};
18932001f49Smrg
19032001f49Smrg/* allow for run-time check for GL_EXT_texture_env_add */
19132001f49Smrgint NUM_ENV_MODES = 5;
19232001f49Smrgstruct envModeInfo envModes[] =
19332001f49Smrg{
19432001f49Smrg   { GL_REPLACE, "REPLACE" },
19532001f49Smrg   { GL_MODULATE, "MODULATE" },
19632001f49Smrg   { GL_BLEND, "BLEND" },
19732001f49Smrg   { GL_DECAL, "DECAL" },
19832001f49Smrg#if GL_EXT_texture_env_add
19932001f49Smrg   { GL_ADD, "ADD" },
20032001f49Smrg#endif
20132001f49Smrg};
20232001f49Smrg
20332001f49Smrgstatic void checkErrors( void )
20432001f49Smrg{
20532001f49Smrg   GLenum error;
20632001f49Smrg
20732001f49Smrg   while ( (error = glGetError()) != GL_NO_ERROR ) {
20832001f49Smrg      fprintf( stderr, "Error: %s\n", (char *) gluErrorString( error ) );
20932001f49Smrg   }
21032001f49Smrg}
21132001f49Smrg
21232001f49Smrgstatic void drawString( const char *string, GLfloat x, GLfloat y,
21332001f49Smrg                        const GLfloat color[4] )
21432001f49Smrg{
21532001f49Smrg   glColor4fv( color );
21632001f49Smrg   glRasterPos2f( x, y );
21732001f49Smrg
21832001f49Smrg   while ( *string ) {
21932001f49Smrg      glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_10, *string );
22032001f49Smrg      string++;
22132001f49Smrg   }
22232001f49Smrg}
22332001f49Smrg
22432001f49Smrgstatic void drawStringOutline( const char *string, GLfloat x, GLfloat y,
22532001f49Smrg			       const GLfloat color[4],
22632001f49Smrg                               const GLfloat outline[4] )
22732001f49Smrg{
22832001f49Smrg   drawString( string, x - 1, y, outline );
22932001f49Smrg   drawString( string, x + 1, y, outline );
23032001f49Smrg   drawString( string, x, y - 1, outline );
23132001f49Smrg   drawString( string, x, y + 1, outline );
23232001f49Smrg   drawString( string, x, y, color );
23332001f49Smrg}
23432001f49Smrg
23532001f49Smrgstatic void begin2D( int width, int height )
23632001f49Smrg{
23732001f49Smrg   glMatrixMode( GL_PROJECTION );
23832001f49Smrg
23932001f49Smrg   glPushMatrix();
24032001f49Smrg   glLoadIdentity();
24132001f49Smrg
24232001f49Smrg   glOrtho( 0, width, 0, height, -1, 1 );
24332001f49Smrg   glMatrixMode( GL_MODELVIEW );
24432001f49Smrg
24532001f49Smrg   glPushMatrix();
24632001f49Smrg   glLoadIdentity();
24732001f49Smrg}
24832001f49Smrg
24932001f49Smrgstatic void end2D( void )
25032001f49Smrg{
25132001f49Smrg   glMatrixMode( GL_PROJECTION );
25232001f49Smrg   glPopMatrix();
25332001f49Smrg   glMatrixMode( GL_MODELVIEW );
25432001f49Smrg   glPopMatrix();
25532001f49Smrg}
25632001f49Smrg
25732001f49Smrgstatic void initialize( void )
25832001f49Smrg{
25932001f49Smrg   glMatrixMode( GL_PROJECTION );
26032001f49Smrg   glLoadIdentity();
26132001f49Smrg
26232001f49Smrg   glOrtho( -1.5, 1.5, -1.5, 1.5, -1.5, 1.5 );
26332001f49Smrg
26432001f49Smrg   glMatrixMode(GL_MODELVIEW);
26532001f49Smrg   glLoadIdentity();
26632001f49Smrg
26732001f49Smrg   glShadeModel( GL_FLAT );
26832001f49Smrg}
26932001f49Smrg
27032001f49Smrg/* ARGSUSED1 */
27132001f49Smrgstatic void keyboard( unsigned char c, int x, int y )
27232001f49Smrg{
27332001f49Smrg   switch ( c ) {
27432001f49Smrg   case 'c':
27532001f49Smrg      envColor++;
27632001f49Smrg      envColor = envColor % (int) NUM_ENV_COLORS;
27732001f49Smrg      break;
27832001f49Smrg   case 'g':
27932001f49Smrg      drawBackground = !drawBackground;
28032001f49Smrg      break;
28132001f49Smrg   case 'b':
28232001f49Smrg      drawBlended = !drawBlended;
28332001f49Smrg      break;
28432001f49Smrg   case 's':
28532001f49Smrg      drawSmooth = !drawSmooth;
28632001f49Smrg      break;
28732001f49Smrg   case 't':
28832001f49Smrg      drawTextured = !drawTextured;
28932001f49Smrg      break;
29032001f49Smrg   case 'i':
29132001f49Smrg      displayLevelInfo = !displayLevelInfo;
29232001f49Smrg      break;
29332001f49Smrg   case 27:             /* Escape key should force exit. */
29432001f49Smrg      glutDestroyWindow(Win);
29532001f49Smrg      exit(0);
29632001f49Smrg      break;
29732001f49Smrg   default:
29832001f49Smrg      break;
29932001f49Smrg   }
30032001f49Smrg   glutPostRedisplay();
30132001f49Smrg}
30232001f49Smrg
30332001f49Smrg/* ARGSUSED1 */
30432001f49Smrgstatic void special( int key, int x, int y )
30532001f49Smrg{
30632001f49Smrg   switch ( key ) {
30732001f49Smrg   case GLUT_KEY_DOWN:
30832001f49Smrg      if ( ++baseFormat > NUM_BASE_FORMATS - 1 ) {
30932001f49Smrg	 baseFormat = 0;
31032001f49Smrg      }
31132001f49Smrg      break;
31232001f49Smrg   case GLUT_KEY_UP:
31332001f49Smrg      if ( --baseFormat < 0 ) {
31432001f49Smrg	 baseFormat = NUM_BASE_FORMATS - 1;
31532001f49Smrg      }
31632001f49Smrg      break;
31732001f49Smrg   case GLUT_KEY_LEFT:
31832001f49Smrg      --baseFormats[baseFormat].current;
31932001f49Smrg      if ( baseFormats[baseFormat].current < 0 ) {
32032001f49Smrg	 baseFormats[baseFormat].current = baseFormats[baseFormat].number - 1;
32132001f49Smrg      }
32232001f49Smrg      break;
32332001f49Smrg   case GLUT_KEY_RIGHT:
32432001f49Smrg      ++baseFormats[baseFormat].current;
32532001f49Smrg      if ( baseFormats[baseFormat].current > baseFormats[baseFormat].number - 1 ) {
32632001f49Smrg	 baseFormats[baseFormat].current = 0;
32732001f49Smrg      }
32832001f49Smrg      break;
32932001f49Smrg   default:
33032001f49Smrg      break;
33132001f49Smrg   }
33232001f49Smrg   glutPostRedisplay();
33332001f49Smrg}
33432001f49Smrg
33532001f49Smrgstatic void
33632001f49Smrgreshape( int w, int h )
33732001f49Smrg{
33832001f49Smrg   winWidth = w;
33932001f49Smrg   winHeight = h;
34032001f49Smrg   /* No need to call glViewPort here since "draw" calls it! */
34132001f49Smrg}
34232001f49Smrg
34332001f49Smrgstatic void loadTexture( int width, int height,
34432001f49Smrg                         const struct formatInfo *format )
34532001f49Smrg{
34632001f49Smrg   int		luminanceSize = 0;
34732001f49Smrg   int		alphaSize = 0;
34832001f49Smrg   int		rgbSize = 0;
34932001f49Smrg   GLenum	textureFormat;
35032001f49Smrg   GLubyte	*texImage, *p;
35132001f49Smrg   int		elementsPerGroup, elementSize, groupSize, rowSize;
35232001f49Smrg   int		i, j;
35332001f49Smrg
35432001f49Smrg   switch ( format->baseFormat ) {
35532001f49Smrg   case GL_LUMINANCE:
35632001f49Smrg      luminanceSize = 1;
35732001f49Smrg      textureFormat = GL_LUMINANCE;
35832001f49Smrg      break;
35932001f49Smrg   case GL_INTENSITY:
36032001f49Smrg      luminanceSize = 1;
36132001f49Smrg      /* Note: format=GL_INTENSITY for glTexImage is not legal */
36232001f49Smrg      textureFormat = GL_LUMINANCE;
36332001f49Smrg      break;
36432001f49Smrg   case GL_ALPHA:
36532001f49Smrg      alphaSize = 1;
36632001f49Smrg      textureFormat = GL_ALPHA;
36732001f49Smrg      break;
36832001f49Smrg   case GL_LUMINANCE_ALPHA:
36932001f49Smrg      luminanceSize = 1;
37032001f49Smrg      alphaSize = 1;
37132001f49Smrg      textureFormat = GL_LUMINANCE_ALPHA;
37232001f49Smrg      break;
37332001f49Smrg   case GL_RGB:
37432001f49Smrg      rgbSize = 3;
37532001f49Smrg      textureFormat = GL_RGB;
37632001f49Smrg      break;
37732001f49Smrg   case GL_RGBA:
37832001f49Smrg      rgbSize = 3;
37932001f49Smrg      alphaSize = 1;
38032001f49Smrg      textureFormat = GL_RGBA;
38132001f49Smrg      break;
38232001f49Smrg   default:
38332001f49Smrg      fprintf(stderr, "bad internal format info\n");
38432001f49Smrg      return;
38532001f49Smrg   }
38632001f49Smrg
38732001f49Smrg   elementsPerGroup = luminanceSize + alphaSize + rgbSize;
38832001f49Smrg   elementSize = sizeof(GLubyte);
38932001f49Smrg   groupSize = elementsPerGroup * elementSize;
39032001f49Smrg   rowSize = width * groupSize;
39132001f49Smrg
39232001f49Smrg   if ( (texImage = (GLubyte *) malloc( height * rowSize ) ) == NULL ) {
39332001f49Smrg      fprintf( stderr, "texture malloc failed\n" );
39432001f49Smrg      return;
39532001f49Smrg   }
39632001f49Smrg
39732001f49Smrg   for ( i = 0 ; i < height ; i++ )
39832001f49Smrg   {
39932001f49Smrg      p = texImage + i * rowSize;
40032001f49Smrg
40132001f49Smrg      for ( j = 0 ; j < width ; j++ )
40232001f49Smrg      {
40332001f49Smrg	 if ( luminanceSize > 0 )
40432001f49Smrg	 {
40532001f49Smrg	    /**
40632001f49Smrg	     ** +-----+-----+
40732001f49Smrg	     ** |     |     |
40832001f49Smrg	     ** |  W  | LG  |
40932001f49Smrg	     ** |     |     |
41032001f49Smrg	     ** +-----+-----+
41132001f49Smrg	     ** |     |     |
41232001f49Smrg	     ** | DG  |  B  |
41332001f49Smrg	     ** |     |     |
41432001f49Smrg	     ** +-----+-----+
41532001f49Smrg	     **/
41632001f49Smrg	    if ( i > height / 2 ) {
41732001f49Smrg	       if ( j < width / 2 ) {
41832001f49Smrg		  p[0] = 0xff;
41932001f49Smrg	       } else {
42032001f49Smrg		  p[0] = 0xaa;
42132001f49Smrg	       }
42232001f49Smrg	    } else {
42332001f49Smrg	       if ( j < width / 2 ) {
42432001f49Smrg		  p[0] = 0x55;
42532001f49Smrg	       } else {
42632001f49Smrg		  p[0] = 0x00;
42732001f49Smrg	       }
42832001f49Smrg	    }
42932001f49Smrg	    p += elementSize;
43032001f49Smrg	 }
43132001f49Smrg
43232001f49Smrg	 if ( rgbSize > 0 )
43332001f49Smrg	 {
43432001f49Smrg	    /**
43532001f49Smrg	     ** +-----+-----+
43632001f49Smrg	     ** |     |     |
43732001f49Smrg	     ** |  R  |  G  |
43832001f49Smrg	     ** |     |     |
43932001f49Smrg	     ** +-----+-----+
44032001f49Smrg	     ** |     |     |
44132001f49Smrg	     ** |  Y  |  B  |
44232001f49Smrg	     ** |     |     |
44332001f49Smrg	     ** +-----+-----+
44432001f49Smrg	     **/
44532001f49Smrg	    if ( i > height / 2 ) {
44632001f49Smrg	       if ( j < width / 2 ) {
44732001f49Smrg		  p[0] = 0xff;
44832001f49Smrg		  p[1] = 0x00;
44932001f49Smrg		  p[2] = 0x00;
45032001f49Smrg	       } else {
45132001f49Smrg		  p[0] = 0x00;
45232001f49Smrg		  p[1] = 0xff;
45332001f49Smrg		  p[2] = 0x00;
45432001f49Smrg	       }
45532001f49Smrg	    } else {
45632001f49Smrg	       if ( j < width / 2 ) {
45732001f49Smrg		  p[0] = 0xff;
45832001f49Smrg		  p[1] = 0xff;
45932001f49Smrg		  p[2] = 0x00;
46032001f49Smrg	       } else {
46132001f49Smrg		  p[0] = 0x00;
46232001f49Smrg		  p[1] = 0x00;
46332001f49Smrg		  p[2] = 0xff;
46432001f49Smrg	       }
46532001f49Smrg	    }
46632001f49Smrg	    p += 3 * elementSize;
46732001f49Smrg	 }
46832001f49Smrg
46932001f49Smrg	 if ( alphaSize > 0 )
47032001f49Smrg	 {
47132001f49Smrg	    /**
47232001f49Smrg	     ** +-----------+
47332001f49Smrg	     ** |     W     |
47432001f49Smrg	     ** |  +-----+  |
47532001f49Smrg	     ** |  |     |  |
47632001f49Smrg	     ** |  |  B  |  |
47732001f49Smrg	     ** |  |     |  |
47832001f49Smrg	     ** |  +-----+  |
47932001f49Smrg	     ** |           |
48032001f49Smrg	     ** +-----------+
48132001f49Smrg	     **/
48232001f49Smrg	    int i2 = i - height / 2;
48332001f49Smrg	    int j2 = j - width / 2;
48432001f49Smrg	    int h8 = height / 8;
48532001f49Smrg	    int w8 = width / 8;
48632001f49Smrg	    if ( -h8 <= i2 && i2 <= h8 && -w8 <= j2 && j2 <= w8 ) {
48732001f49Smrg	       p[0] = 0x00;
48832001f49Smrg	    } else if ( -2 * h8 <= i2 && i2 <= 2 * h8 && -2 * w8 <= j2 && j2 <= 2 * w8 ) {
48932001f49Smrg	       p[0] = 0x55;
49032001f49Smrg	    } else if ( -3 * h8 <= i2 && i2 <= 3 * h8 && -3 * w8 <= j2 && j2 <= 3 * w8 ) {
49132001f49Smrg	       p[0] = 0xaa;
49232001f49Smrg	    } else {
49332001f49Smrg	       p[0] = 0xff;
49432001f49Smrg	    }
49532001f49Smrg	    p += elementSize;
49632001f49Smrg	 }
49732001f49Smrg      }
49832001f49Smrg   }
49932001f49Smrg
50032001f49Smrg   glTexImage2D( GL_TEXTURE_2D, 0,
50132001f49Smrg		 format->internalFormat, width, height, 0,
50232001f49Smrg		 textureFormat, GL_UNSIGNED_BYTE, texImage );
50332001f49Smrg
50432001f49Smrg   free( texImage );
50532001f49Smrg}
50632001f49Smrg
50732001f49Smrgstatic void drawCheck( int w, int h, const GLfloat lightCheck[4],
50832001f49Smrg                       const GLfloat darkCheck[4] )
50932001f49Smrg{
51032001f49Smrg   float	dw = 2.0 / w;
51132001f49Smrg   float	dh = 2.0 / h;
51232001f49Smrg   int		i, j;
51332001f49Smrg
51432001f49Smrg   for ( i = 0 ; i < w ; i++ ) {
51532001f49Smrg      GLfloat x0 = -1.0 + i * dw;
51632001f49Smrg      GLfloat x1 = x0 + dw;
51732001f49Smrg
51832001f49Smrg      glBegin( GL_QUAD_STRIP );
51932001f49Smrg
52032001f49Smrg      for ( j = 0 ; j <= h ; j++ ) {
52132001f49Smrg	 GLfloat y = -1.0 + j * dh;
52232001f49Smrg
52332001f49Smrg	 if ( (i ^ j) & 1 ) {
52432001f49Smrg	    glColor4fv( lightCheck );
52532001f49Smrg	 } else {
52632001f49Smrg	    glColor4fv( darkCheck );
52732001f49Smrg	 }
52832001f49Smrg
52932001f49Smrg	 glVertex2f( x0, y );
53032001f49Smrg	 glVertex2f( x1, y );
53132001f49Smrg      }
53232001f49Smrg
53332001f49Smrg      glEnd();
53432001f49Smrg   }
53532001f49Smrg}
53632001f49Smrg
53732001f49Smrgstatic const char *lookupFormat( GLint format )
53832001f49Smrg{
53932001f49Smrg   switch ( format ) {
54032001f49Smrg   case GL_RGBA:
54132001f49Smrg      return "GL_RGBA";
54232001f49Smrg   case GL_RGB:
54332001f49Smrg      return "GL_RGB";
54432001f49Smrg   case GL_ALPHA:
54532001f49Smrg      return "GL_ALPHA";
54632001f49Smrg   case GL_LUMINANCE:
54732001f49Smrg      return "GL_LUMINANCE";
54832001f49Smrg   case GL_LUMINANCE_ALPHA:
54932001f49Smrg      return "GL_LUMINANCE_ALPHA";
55032001f49Smrg   case GL_INTENSITY:
55132001f49Smrg      return "GL_INTENSITY";
55232001f49Smrg   case GL_COLOR_INDEX:
55332001f49Smrg      return "GL_COLOR_INDEX";
55432001f49Smrg   case GL_BGRA:
55532001f49Smrg      return "GL_BGRA";
55632001f49Smrg   case GL_BGR:
55732001f49Smrg      return "GL_BGR";
55832001f49Smrg   default:
55932001f49Smrg      return "unknown format";
56032001f49Smrg   }
56132001f49Smrg}
56232001f49Smrg
56332001f49Smrgstatic void drawSample( int x, int y, int w, int h,
56432001f49Smrg			const struct formatInfo *format,
56532001f49Smrg                        const struct envModeInfo *envMode )
56632001f49Smrg{
56732001f49Smrg   glViewport( x, y, w, h );
56832001f49Smrg   glScissor( x, y, w, h );
56932001f49Smrg
57032001f49Smrg   glClearColor( 0.1, 0.1, 0.1, 1.0 );
57132001f49Smrg   glClear( GL_COLOR_BUFFER_BIT );
57232001f49Smrg
57332001f49Smrg   begin2D( w, h );
57432001f49Smrg   drawString( format->name, 10, h - 15, labelInfoColor );
57532001f49Smrg   drawString( envMode->name, 10, 5, labelInfoColor );
57632001f49Smrg   end2D();
57732001f49Smrg
57832001f49Smrg   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, envMode->mode );
57932001f49Smrg   glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColors[envColor] );
58032001f49Smrg
58132001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
58232001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
58332001f49Smrg
58432001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
58532001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
58632001f49Smrg
58732001f49Smrg   loadTexture( textureWidth, textureHeight, format );
58832001f49Smrg
58932001f49Smrg   if ( drawBackground ) {
59032001f49Smrg      drawCheck( 15, 15, lightCheck, darkCheck );
59132001f49Smrg   }
59232001f49Smrg   if ( drawBlended ) {
59332001f49Smrg      glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
59432001f49Smrg      glEnable( GL_BLEND );
59532001f49Smrg   }
59632001f49Smrg   if ( drawSmooth ) {
59732001f49Smrg      glShadeModel( GL_SMOOTH );
59832001f49Smrg   }
59932001f49Smrg   else {
60032001f49Smrg      glShadeModel( GL_FLAT );
60132001f49Smrg      glColor4f(1, 1, 1, 1);
60232001f49Smrg   }
60332001f49Smrg   if ( drawTextured ) {
60432001f49Smrg      glEnable( GL_TEXTURE_2D );
60532001f49Smrg   }
60632001f49Smrg
60732001f49Smrg   /*
60832001f49Smrg    * if (drawSmooth) then draw quad which goes from purple at the
60932001f49Smrg    * bottom (100% alpha) to green at the top (50% alpha).
61032001f49Smrg    */
61132001f49Smrg   glBegin( GL_QUADS );
61232001f49Smrg      if ( drawSmooth )  glColor4f( 1.0, 0.0, 1.0, 1.0 );
61332001f49Smrg      glTexCoord2f( 0.0, 0.0 );
61432001f49Smrg      glVertex2f( -0.8, -0.8 );
61532001f49Smrg
61632001f49Smrg      if ( drawSmooth )  glColor4f( 1.0, 0.0, 1.0, 1.0 );
61732001f49Smrg      glTexCoord2f( 1.0, 0.0 );
61832001f49Smrg      glVertex2f( 0.8, -0.8 );
61932001f49Smrg
62032001f49Smrg      if ( drawSmooth )  glColor4f( 0.0, 1.0, 0.0, 0.5 );
62132001f49Smrg      glTexCoord2f( 1.0, 1.0 );
62232001f49Smrg      glVertex2f( 0.8, 0.8 );
62332001f49Smrg
62432001f49Smrg      if ( drawSmooth )  glColor4f( 0.0, 1.0, 0.0, 0.5 );
62532001f49Smrg      glTexCoord2f( 0.0, 1.0 );
62632001f49Smrg      glVertex2f( -0.8, 0.8 );
62732001f49Smrg   glEnd();
62832001f49Smrg
62932001f49Smrg   glDisable( GL_BLEND );
63032001f49Smrg   glShadeModel( GL_FLAT );
63132001f49Smrg   glDisable( GL_TEXTURE_2D );
63232001f49Smrg
63332001f49Smrg   if ( envMode->mode == GL_DECAL &&
63432001f49Smrg        (format->baseFormat == GL_ALPHA ||
63532001f49Smrg         format->baseFormat == GL_LUMINANCE ||
63632001f49Smrg         format->baseFormat == GL_LUMINANCE_ALPHA ||
63732001f49Smrg         format->baseFormat == GL_INTENSITY)) {
63832001f49Smrg      /* undefined format/mode combination */
63932001f49Smrg      begin2D( w, h );
64032001f49Smrg      drawStringOutline( "UNDEFINED MODE", 15, h / 2,
64132001f49Smrg                         labelLevelColor0, labelLevelColor1 );
64232001f49Smrg      end2D();
64332001f49Smrg   }
64432001f49Smrg   else if ( displayLevelInfo ) {
64532001f49Smrg      GLint width, height, border, format;
64632001f49Smrg      GLint redSize, greenSize, blueSize, alphaSize;
64732001f49Smrg      GLint luminanceSize, intensitySize;
64832001f49Smrg      char buf[255];
64932001f49Smrg
65032001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width );
65132001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height );
65232001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border );
65332001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format );
65432001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &redSize );
65532001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &greenSize );
65632001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &blueSize );
65732001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alphaSize );
65832001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &luminanceSize );
65932001f49Smrg      glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &intensitySize );
66032001f49Smrg
66132001f49Smrg      begin2D( w, h );
66232001f49Smrg      sprintf( buf, "dimensions: %d x %d", width, height );
66332001f49Smrg      drawStringOutline( buf, 15, h / 2 + 20, labelLevelColor0, labelLevelColor1 );
66432001f49Smrg
66532001f49Smrg      sprintf( buf, "border: %d", border );
66632001f49Smrg      drawStringOutline( buf, 15, h / 2 + 10, labelLevelColor0, labelLevelColor1 );
66732001f49Smrg
66832001f49Smrg      sprintf( buf, "internal format:" );
66932001f49Smrg      drawStringOutline( buf, 15, h / 2, labelLevelColor0, labelLevelColor1 );
67032001f49Smrg
67132001f49Smrg      sprintf( buf, "  %s",  lookupFormat( format ) );
67232001f49Smrg      drawStringOutline( buf, 15, h / 2 - 10, labelLevelColor0, labelLevelColor1 );
67332001f49Smrg
67432001f49Smrg      sprintf( buf, "sizes:" );
67532001f49Smrg      drawStringOutline( buf, 15, h / 2 - 20, labelLevelColor0, labelLevelColor1 );
67632001f49Smrg
67732001f49Smrg      sprintf( buf, "  %d / %d / %d / %d / %d / %d",
67832001f49Smrg	       redSize, greenSize, blueSize, alphaSize,
67932001f49Smrg	       luminanceSize, intensitySize );
68032001f49Smrg      drawStringOutline( buf, 15, h / 2 - 30, labelLevelColor0, labelLevelColor1 );
68132001f49Smrg
68232001f49Smrg      end2D();
68332001f49Smrg   }
68432001f49Smrg}
68532001f49Smrg
68632001f49Smrgstatic void display( void )
68732001f49Smrg{
68832001f49Smrg   int		numX = NUM_ENV_MODES, numY = NUM_BASE_FORMATS;
68932001f49Smrg   float	xBase = (float) winWidth * 0.01;
69032001f49Smrg   float	xOffset = (winWidth - xBase) / numX;
69132001f49Smrg   float	xSize = max( xOffset - xBase, 1 );
69232001f49Smrg   float	yBase = (float) winHeight * 0.01;
69332001f49Smrg   float	yOffset = (winHeight - yBase) / numY;
69432001f49Smrg   float	ySize = max( yOffset - yBase, 1 );
69532001f49Smrg   float	x, y;
69632001f49Smrg   int		i, j;
69732001f49Smrg
69832001f49Smrg   glViewport( 0, 0, winWidth, winHeight );
69932001f49Smrg   glDisable( GL_SCISSOR_TEST );
70032001f49Smrg   glClearColor( 0.0, 0.0, 0.0, 0.0 );
70132001f49Smrg   glClear( GL_COLOR_BUFFER_BIT );
70232001f49Smrg   glEnable( GL_SCISSOR_TEST );
70332001f49Smrg
70432001f49Smrg   x = xBase;
70532001f49Smrg   y = (winHeight - 1) - yOffset;
70632001f49Smrg
70732001f49Smrg   for ( i = 0 ; i < NUM_BASE_FORMATS ; i++ )
70832001f49Smrg   {
70932001f49Smrg      struct formatInfo *format;
71032001f49Smrg
71132001f49Smrg      if ( i == baseFormat ) {
71232001f49Smrg	 labelInfoColor = labelColor1;
71332001f49Smrg      } else {
71432001f49Smrg	 labelInfoColor = labelColor0;
71532001f49Smrg      }
71632001f49Smrg
71732001f49Smrg      format = &baseFormats[i].format[baseFormats[i].current];
71832001f49Smrg
71932001f49Smrg      for ( j = 0 ; j < NUM_ENV_MODES ; j++ ) {
72032001f49Smrg	 struct envModeInfo *envMode;
72132001f49Smrg
72232001f49Smrg	 envMode = &envModes[j];
72332001f49Smrg	 drawSample( x, y, xSize, ySize, format, envMode );
72432001f49Smrg	 x += xOffset;
72532001f49Smrg      }
72632001f49Smrg
72732001f49Smrg      x = xBase;
72832001f49Smrg      y -= yOffset;
72932001f49Smrg   }
73032001f49Smrg
73132001f49Smrg   if ( doubleBuffered ) {
73232001f49Smrg      glutSwapBuffers();
73332001f49Smrg   } else {
73432001f49Smrg      glFlush();
73532001f49Smrg   }
73632001f49Smrg
73732001f49Smrg   checkErrors();
73832001f49Smrg}
73932001f49Smrg
74032001f49Smrgstatic void usage( char *name )
74132001f49Smrg{
74232001f49Smrg   fprintf( stderr, "usage: %s [ options ]\n", name );
74332001f49Smrg   fprintf( stderr, "\n" );
74432001f49Smrg   fprintf( stderr, "options:\n" );
74532001f49Smrg   fprintf( stderr, "    -sb    single buffered\n" );
74632001f49Smrg   fprintf( stderr, "    -db    double buffered\n" );
74732001f49Smrg   fprintf( stderr, "    -info  print OpenGL driver info\n" );
74832001f49Smrg}
74932001f49Smrg
75032001f49Smrgstatic void instructions( void )
75132001f49Smrg{
75232001f49Smrg   fprintf( stderr, "texenv - texture environment and internal format test\n" );
75332001f49Smrg   fprintf( stderr, "\n" );
75432001f49Smrg   fprintf( stderr, "  [c] - cycle through background colors\n" );
75532001f49Smrg   fprintf( stderr, "  [g] - toggle background\n" );
75632001f49Smrg   fprintf( stderr, "  [b] - toggle blend\n" );
75732001f49Smrg   fprintf( stderr, "  [s] - toggle smooth shading\n" );
75832001f49Smrg   fprintf( stderr, "  [t] - toggle texturing\n" );
75932001f49Smrg   fprintf( stderr, "  [i] - toggle information display\n" );
76032001f49Smrg   fprintf( stderr, "  up/down - select row\n" );
76132001f49Smrg   fprintf( stderr, "  left/right - change row's internal format\n" );
76232001f49Smrg}
76332001f49Smrg
76432001f49Smrgint main( int argc, char *argv[] )
76532001f49Smrg{
76632001f49Smrg   GLboolean info = GL_FALSE;
76732001f49Smrg   int i;
76832001f49Smrg
76932001f49Smrg   glutInitWindowSize( winWidth, winHeight );
77032001f49Smrg   glutInit( &argc, argv );
77132001f49Smrg
77232001f49Smrg   for ( i = 1 ; i < argc ; i++ ) {
77332001f49Smrg      if ( !strcmp( "-sb", argv[i] ) ) {
77432001f49Smrg	 doubleBuffered = GL_FALSE;
77532001f49Smrg      } else if ( !strcmp( "-db", argv[i] ) ) {
77632001f49Smrg	 doubleBuffered = GL_TRUE;
77732001f49Smrg      } else if ( !strcmp( "-info", argv[i] ) ) {
77832001f49Smrg	 info = GL_TRUE;
77932001f49Smrg      } else {
78032001f49Smrg	 usage( argv[0] );
78132001f49Smrg	 exit( 1 );
78232001f49Smrg      }
78332001f49Smrg   }
78432001f49Smrg
78532001f49Smrg   if ( doubleBuffered ) {
78632001f49Smrg      glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
78732001f49Smrg   } else {
78832001f49Smrg      glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );
78932001f49Smrg   }
79032001f49Smrg
79132001f49Smrg   Win = glutCreateWindow( "Texture Environment Test" );
79232001f49Smrg
79332001f49Smrg   initialize();
79432001f49Smrg   instructions();
79532001f49Smrg
79632001f49Smrg   if ( info ) {
79732001f49Smrg      printf( "\n" );
79832001f49Smrg      printf( "GL_RENDERER   = %s\n", (char *) glGetString( GL_RENDERER ) );
79932001f49Smrg      printf( "GL_VERSION    = %s\n", (char *) glGetString( GL_VERSION ) );
80032001f49Smrg      printf( "GL_VENDOR     = %s\n", (char *) glGetString( GL_VENDOR ) ) ;
80132001f49Smrg      printf( "GL_EXTENSIONS = %s\n", (char *) glGetString( GL_EXTENSIONS ) );
80232001f49Smrg   }
80332001f49Smrg
80432001f49Smrg#if GL_EXT_texture_env_add
80532001f49Smrg   if ( !glutExtensionSupported( "GL_EXT_texture_env_add" ) ) {
80632001f49Smrg      fprintf( stderr, "missing extension: GL_EXT_texture_env_add\n" );
80732001f49Smrg      NUM_ENV_MODES--;
80832001f49Smrg   }
80932001f49Smrg#endif
81032001f49Smrg
81132001f49Smrg   glutDisplayFunc( display );
81232001f49Smrg   glutReshapeFunc( reshape );
81332001f49Smrg   glutKeyboardFunc( keyboard );
81432001f49Smrg   glutSpecialFunc( special );
81532001f49Smrg   glutMainLoop();
81632001f49Smrg
81732001f49Smrg   return 0;
81832001f49Smrg}
819