OSDN Git Service

52c504a31880d3dac72dc573fb598d248c403d99
[android-x86/external-mesa.git] / progs / tests / texcmp.c
1 /*
2  * Compressed texture demo.  Written by Daniel Borca.
3  * This program is in the public domain.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <math.h>
9 #include <string.h>
10 #include <GL/glew.h>
11 #include <GL/glut.h>
12
13 #include "readtex.c" /* I know, this is a hack. */
14 #define TEXTURE_FILE "../images/tree2.rgba"
15
16
17 static float Rot = 0.0;
18 static GLboolean Anim = 1;
19
20 typedef struct {
21         GLubyte *data;
22         GLuint size;
23         GLenum format;
24         GLuint w, h;
25
26         GLenum TC;
27
28         GLubyte *cData;
29         GLuint cSize;
30         GLenum cFormat;
31 } TEXTURE;
32
33 static TEXTURE *Tx, t1, t2, t3;
34 static GLboolean fxt1, dxtc, s3tc;
35
36
37 static const char *TextureName (GLenum TC)
38 {
39  switch (TC) {
40         case GL_RGB:
41              return "RGB";
42         case GL_RGBA:
43              return "RGBA";
44         case GL_COMPRESSED_RGB:
45              return "COMPRESSED_RGB";
46         case GL_COMPRESSED_RGBA:
47              return "COMPRESSED_RGBA";
48         case GL_COMPRESSED_RGB_FXT1_3DFX:
49              return "GL_COMPRESSED_RGB_FXT1_3DFX";
50         case GL_COMPRESSED_RGBA_FXT1_3DFX:
51              return "GL_COMPRESSED_RGBA_FXT1_3DFX";
52         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
53              return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT";
54         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
55              return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT";
56         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
57              return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT";
58         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
59              return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT";
60         case GL_RGB_S3TC:
61              return "GL_RGB_S3TC";
62         case GL_RGB4_S3TC:
63              return "GL_RGB4_S3TC";
64         case GL_RGBA_S3TC:
65              return "GL_RGBA_S3TC";
66         case GL_RGBA4_S3TC:
67              return "GL_RGBA4_S3TC";
68         case 0:
69              return "Invalid format";
70         default:
71              return "Unknown format";
72  }
73 }
74
75
76 static void
77 PrintString(const char *s)
78 {
79    while (*s) {
80       glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
81       s++;
82    }
83 }
84
85
86 static void Idle( void )
87 {
88    float t = glutGet(GLUT_ELAPSED_TIME) * 0.001;  /* in seconds */
89    Rot = t * 360 / 4;  /* 1 rotation per 4 seconds */
90    glutPostRedisplay();
91 }
92
93
94 static void Display( void )
95 {
96    /* draw background gradient */
97    glDisable(GL_TEXTURE_2D);
98    glBegin(GL_POLYGON);
99    glColor3f(1.0, 0.0, 0.2); glVertex2f(-1.5, -1.0);
100    glColor3f(1.0, 0.0, 0.2); glVertex2f( 1.5, -1.0);
101    glColor3f(0.0, 0.0, 1.0); glVertex2f( 1.5,  1.0);
102    glColor3f(0.0, 0.0, 1.0); glVertex2f(-1.5,  1.0);
103    glEnd();
104
105    glPushMatrix();
106    glRotatef(Rot, 0, 0, 1);
107
108    glEnable(GL_TEXTURE_2D);
109    glBegin(GL_POLYGON);
110    glTexCoord2f(0, 1);  glVertex2f(-1, -0.5);
111    glTexCoord2f(1, 1);  glVertex2f( 1, -0.5);
112    glTexCoord2f(1, 0);  glVertex2f( 1,  0.5);
113    glTexCoord2f(0, 0);  glVertex2f(-1,  0.5);
114    glEnd();
115
116    glPopMatrix();
117
118    /* info */
119    glColor4f(1, 1, 1, 1);
120
121    glRasterPos3f(-1.2, -0.7, 0);
122    PrintString("Selected: ");
123    PrintString(TextureName(Tx->TC));
124    if (Tx->cData) {
125       char tmp[64];
126       glRasterPos3f(-1.2, -0.8, 0);
127       PrintString("Internal: ");
128       PrintString(TextureName(Tx->cFormat));
129       glRasterPos3f(-1.2, -0.9, 0);
130       PrintString("Size    : ");
131       sprintf(tmp, "%d (%d%% of %d)", Tx->cSize, Tx->cSize * 100 / Tx->size, Tx->size);
132       PrintString(tmp);
133    }
134
135    glutSwapBuffers();
136 }
137
138
139 static void Reshape( int width, int height )
140 {
141    glViewport( 0, 0, width, height );
142    glMatrixMode( GL_PROJECTION );
143    glLoadIdentity();
144    glOrtho( -1.5, 1.5, -1.0, 1.0, -1.0, 1.0 );
145    glMatrixMode( GL_MODELVIEW );
146    glLoadIdentity();
147 }
148
149
150 static void ReInit( GLenum TC, TEXTURE *Tx )
151 {
152    GLint rv;
153
154    if ((Tx->TC == TC) && (Tx->cData != NULL)) {
155       glCompressedTexImage2DARB(GL_TEXTURE_2D, /* target */
156                                 0,             /* level */
157                                 Tx->cFormat,   /* real format */
158                                 Tx->w,         /* original width */
159                                 Tx->h,         /* original height */
160                                 0,             /* border */
161                                 Tx->cSize,     /* compressed size*/
162                                 Tx->cData);    /* compressed data*/
163    } else {
164       glTexImage2D(GL_TEXTURE_2D,    /* target */
165                    0,                /* level */
166                    TC,               /* internal format */
167                    Tx->w, Tx->h,     /* width, height */
168                    0,                /* border */
169                    Tx->format,       /* texture format */
170                    GL_UNSIGNED_BYTE, /* texture type */
171                    Tx->data);        /* the texture */
172
173       /* okay, now cache the compressed texture */
174       Tx->TC = TC;
175       if (Tx->cData != NULL) {
176          free(Tx->cData);
177          Tx->cData = NULL;
178       }
179       glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, &rv);
180       if (rv) {
181          glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&Tx->cFormat);
182          glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, (GLint *)&Tx->cSize);
183          if ((Tx->cData = malloc(Tx->cSize)) != NULL) {
184             glGetCompressedTexImageARB(GL_TEXTURE_2D, 0, Tx->cData);
185          }
186       }
187    }
188 }
189
190
191 static void Init( void )
192 {
193    /* HEIGHT * WIDTH + 1 (for trailing '\0') */
194    static char pattern[8 * 32 + 1] = {"\
195                                 \
196     MMM    EEEE   SSS    AAA    \
197    M M M  E      S   S  A   A   \
198    M M M  EEEE    SS    A   A   \
199    M M M  E         SS  AAAAA   \
200    M   M  E      S   S  A   A   \
201    M   M   EEEE   SSS   A   A   \
202                                 "
203       };
204
205    GLuint i, j;
206
207    GLubyte (*texture1)[8 * 32][4];
208    GLubyte (*texture2)[256][256][4];
209
210    t1.w = 32;
211    t1.h = 8;
212    t1.size = t1.w * t1.h * 4;
213    t1.data = malloc(t1.size);
214    t1.format = GL_RGBA;
215    t1.TC = GL_RGBA;
216
217    texture1 = (GLubyte (*)[8 * 32][4])t1.data;
218    for (i = 0; i < sizeof(pattern) - 1; i++) {
219        switch (pattern[i]) {
220               default:
221               case ' ':
222                    (*texture1)[i][0] = 255;
223                    (*texture1)[i][1] = 255;
224                    (*texture1)[i][2] = 255;
225                    (*texture1)[i][3] = 64;
226                    break;
227               case 'M':
228                    (*texture1)[i][0] = 255;
229                    (*texture1)[i][1] = 0;
230                    (*texture1)[i][2] = 0;
231                    (*texture1)[i][3] = 255;
232                    break;
233               case 'E':
234                    (*texture1)[i][0] = 0;
235                    (*texture1)[i][1] = 255;
236                    (*texture1)[i][2] = 0;
237                    (*texture1)[i][3] = 255;
238                    break;
239               case 'S':
240                    (*texture1)[i][0] = 0;
241                    (*texture1)[i][1] = 0;
242                    (*texture1)[i][2] = 255;
243                    (*texture1)[i][3] = 255;
244                    break;
245               case 'A':
246                    (*texture1)[i][0] = 255;
247                    (*texture1)[i][1] = 255;
248                    (*texture1)[i][2] = 0;
249                    (*texture1)[i][3] = 255;
250                    break;
251        }
252    }
253
254    t2.w = 256;
255    t2.h = 256;
256    t2.size = t2.w * t2.h * 4;
257    t2.data = malloc(t2.size);
258    t2.format = GL_RGBA;
259    t2.TC = GL_RGBA;
260
261    texture2 = (GLubyte (*)[256][256][4])t2.data;
262    for (j = 0; j < t2.h; j++) {
263       for (i = 0; i < t2.w; i++) {
264          (*texture2)[j][i][0] = sqrt(i * j * 255 * 255 / (t2.w * t2.h));
265          (*texture2)[j][i][1] = 0;
266          (*texture2)[j][i][2] = 0;
267          (*texture2)[j][i][3] = 255;
268       }
269    }
270
271    t3.data = LoadRGBImage(TEXTURE_FILE, (GLint *)&t3.w, (GLint *)&t3.h, &t3.format);
272    t3.size = t3.w * t3.h * ((t3.format == GL_RGB) ? 3 : 4);
273    t3.TC = GL_RGBA;
274
275    ReInit(GL_RGBA, Tx = &t1);
276
277    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
278    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
279    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
280    glEnable(GL_TEXTURE_2D);
281
282    glEnable(GL_BLEND);
283    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
284 }
285
286
287 static void Key( unsigned char key, int x, int y )
288 {
289    (void) x;
290    (void) y;
291    switch (key) {
292       case 27:
293          exit(0);
294          break;
295       case ' ':
296          Anim = !Anim;
297          if (Anim)
298             glutIdleFunc( Idle );
299          else
300             glutIdleFunc( NULL );
301          break;
302       case 't':
303          if (Tx == &t1) {
304             Tx = &t2;
305          } else if (Tx == &t2) {
306             Tx = &t3;
307          } else {
308             Tx = &t1;
309          }
310          ReInit(Tx->TC, Tx);
311          break;
312       case '9':
313          ReInit(GL_RGB, Tx);
314          break;
315       case '0':
316          ReInit(GL_RGBA, Tx);
317          break;
318       case '1':
319          ReInit(GL_COMPRESSED_RGB, Tx);
320          break;
321       case '2':
322          ReInit(GL_COMPRESSED_RGBA, Tx);
323          break;
324       case '3':
325          if (fxt1) ReInit(GL_COMPRESSED_RGB_FXT1_3DFX, Tx);
326          break;
327       case '4':
328          if (fxt1) ReInit(GL_COMPRESSED_RGBA_FXT1_3DFX, Tx);
329          break;
330       case '5':
331          if (dxtc) ReInit(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, Tx);
332          break;
333       case '6':
334          if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, Tx);
335          break;
336       case '7':
337          if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, Tx);
338          break;
339       case '8':
340          if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, Tx);
341          break;
342       case 'a':
343          if (s3tc) ReInit(GL_RGB_S3TC, Tx);
344          break;
345       case 's':
346          if (s3tc) ReInit(GL_RGB4_S3TC, Tx);
347          break;
348       case 'd':
349          if (s3tc) ReInit(GL_RGBA_S3TC, Tx);
350          break;
351       case 'f':
352          if (s3tc) ReInit(GL_RGBA4_S3TC, Tx);
353          break;
354    }
355    glutPostRedisplay();
356 }
357
358
359 int main( int argc, char *argv[] )
360 {
361    float gl_version;
362    GLint num_formats;
363    GLint i;
364    GLint formats[64];
365
366
367    glutInit( &argc, argv );
368    glutInitWindowPosition( 0, 0 );
369    glutInitWindowSize( 400, 300 );
370
371    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
372
373    if (glutCreateWindow(argv[0]) <= 0) {
374       glewInit();
375       printf("Couldn't create window\n");
376       exit(0);
377    }
378
379    gl_version = atof( (const char *) glGetString( GL_VERSION ) );
380    if ( (gl_version < 1.3) 
381         && !glutExtensionSupported("GL_ARB_texture_compression") ) {
382       printf("Sorry, GL_ARB_texture_compression not supported\n");
383       exit(0);
384    }
385    if (glutExtensionSupported("GL_3DFX_texture_compression_FXT1")) {
386       fxt1 = GL_TRUE;
387    }
388    if (glutExtensionSupported("GL_EXT_texture_compression_s3tc")) {
389       dxtc = GL_TRUE;
390    }
391    if (glutExtensionSupported("GL_S3_s3tc")) {
392       s3tc = GL_TRUE;
393    }
394
395    glGetIntegerv( GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, & num_formats );
396    
397    (void) memset( formats, 0, sizeof( formats ) );
398    glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats );
399
400    printf( "The following texture formats are supported:\n" );
401    for ( i = 0 ; i < num_formats ; i++ ) {
402       printf( "\t%s\n", TextureName( formats[i] ) );
403    }
404         
405    Init();
406
407    glutReshapeFunc( Reshape );
408    glutKeyboardFunc( Key );
409    glutDisplayFunc( Display );
410    if (Anim)
411       glutIdleFunc( Idle );
412
413    glutMainLoop();
414    return 0;
415 }