progs/tests: also test stencil INCR_WRAP mode if supported
[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 glEnable(GL_BLEND);
110
111 glBegin(GL_POLYGON);
112 glTexCoord2f(0, 1); glVertex2f(-1, -0.5);
113 glTexCoord2f(1, 1); glVertex2f( 1, -0.5);
114 glTexCoord2f(1, 0); glVertex2f( 1, 0.5);
115 glTexCoord2f(0, 0); glVertex2f(-1, 0.5);
116 glEnd();
117
118 glPopMatrix();
119
120 glDisable(GL_TEXTURE_2D);
121
122 /* info */
123 glDisable(GL_BLEND);
124 glColor4f(1, 1, 1, 1);
125
126 glRasterPos3f(-1.2, -0.7, 0);
127 PrintString("Selected: ");
128 PrintString(TextureName(Tx->TC));
129 if (Tx->cData) {
130 char tmp[64];
131 glRasterPos3f(-1.2, -0.8, 0);
132 PrintString("Internal: ");
133 PrintString(TextureName(Tx->cFormat));
134 glRasterPos3f(-1.2, -0.9, 0);
135 PrintString("Size : ");
136 sprintf(tmp, "%d (%d%% of %d)", Tx->cSize, Tx->cSize * 100 / Tx->size, Tx->size);
137 PrintString(tmp);
138 }
139
140 glutSwapBuffers();
141 }
142
143
144 static void Reshape( int width, int height )
145 {
146 glViewport( 0, 0, width, height );
147 glMatrixMode( GL_PROJECTION );
148 glLoadIdentity();
149 glOrtho( -1.5, 1.5, -1.0, 1.0, -1.0, 1.0 );
150 glMatrixMode( GL_MODELVIEW );
151 glLoadIdentity();
152 }
153
154
155 static void ReInit( GLenum TC, TEXTURE *Tx )
156 {
157 GLint rv, v;
158
159 if ((Tx->TC == TC) && (Tx->cData != NULL)) {
160 glCompressedTexImage2DARB(GL_TEXTURE_2D, /* target */
161 0, /* level */
162 Tx->cFormat, /* real format */
163 Tx->w, /* original width */
164 Tx->h, /* original height */
165 0, /* border */
166 Tx->cSize, /* compressed size*/
167 Tx->cData); /* compressed data*/
168 } else {
169 glTexImage2D(GL_TEXTURE_2D, /* target */
170 0, /* level */
171 TC, /* internal format */
172 Tx->w, Tx->h, /* width, height */
173 0, /* border */
174 Tx->format, /* texture format */
175 GL_UNSIGNED_BYTE, /* texture type */
176 Tx->data); /* the texture */
177
178
179 v = 0;
180 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
181 GL_TEXTURE_INTERNAL_FORMAT, &v);
182 printf("Requested internal format = 0x%x, actual = 0x%x\n", TC, v);
183
184 if (0) {
185 GLint r, g, b, a, l, i;
186 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
187 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
188 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
189 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
190 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l);
191 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i);
192 printf("Compressed Bits per R: %d G: %d B: %d A: %d L: %d I: %d\n",
193 r, g, b, a, l, i);
194 }
195
196 /* okay, now cache the compressed texture */
197 Tx->TC = TC;
198 if (Tx->cData != NULL) {
199 free(Tx->cData);
200 Tx->cData = NULL;
201 }
202 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, &rv);
203 if (rv) {
204 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&Tx->cFormat);
205 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, (GLint *)&Tx->cSize);
206 if ((Tx->cData = malloc(Tx->cSize)) != NULL) {
207 glGetCompressedTexImageARB(GL_TEXTURE_2D, 0, Tx->cData);
208 }
209 }
210 }
211 }
212
213
214 static void Init( void )
215 {
216 /* HEIGHT * WIDTH + 1 (for trailing '\0') */
217 static char pattern[8 * 32 + 1] = {"\
218 \
219 MMM EEEE SSS AAA \
220 M M M E S S A A \
221 M M M EEEE SS A A \
222 M M M E SS AAAAA \
223 M M E S S A A \
224 M M EEEE SSS A A \
225 "
226 };
227
228 GLuint i, j;
229
230 GLubyte (*texture1)[8 * 32][4];
231 GLubyte (*texture2)[256][256][4];
232
233 t1.w = 32;
234 t1.h = 8;
235 t1.size = t1.w * t1.h * 4;
236 t1.data = malloc(t1.size);
237 t1.format = GL_RGBA;
238 t1.TC = GL_RGBA;
239
240 texture1 = (GLubyte (*)[8 * 32][4])t1.data;
241 for (i = 0; i < sizeof(pattern) - 1; i++) {
242 switch (pattern[i]) {
243 default:
244 case ' ':
245 (*texture1)[i][0] = 255;
246 (*texture1)[i][1] = 255;
247 (*texture1)[i][2] = 255;
248 (*texture1)[i][3] = 64;
249 break;
250 case 'M':
251 (*texture1)[i][0] = 255;
252 (*texture1)[i][1] = 0;
253 (*texture1)[i][2] = 0;
254 (*texture1)[i][3] = 255;
255 break;
256 case 'E':
257 (*texture1)[i][0] = 0;
258 (*texture1)[i][1] = 255;
259 (*texture1)[i][2] = 0;
260 (*texture1)[i][3] = 255;
261 break;
262 case 'S':
263 (*texture1)[i][0] = 0;
264 (*texture1)[i][1] = 0;
265 (*texture1)[i][2] = 255;
266 (*texture1)[i][3] = 255;
267 break;
268 case 'A':
269 (*texture1)[i][0] = 255;
270 (*texture1)[i][1] = 255;
271 (*texture1)[i][2] = 0;
272 (*texture1)[i][3] = 255;
273 break;
274 }
275 }
276
277 t2.w = 256;
278 t2.h = 256;
279 t2.size = t2.w * t2.h * 4;
280 t2.data = malloc(t2.size);
281 t2.format = GL_RGBA;
282 t2.TC = GL_RGBA;
283
284 texture2 = (GLubyte (*)[256][256][4])t2.data;
285 for (j = 0; j < t2.h; j++) {
286 for (i = 0; i < t2.w; i++) {
287 (*texture2)[j][i][0] = sqrt(i * j * 255 * 255 / (t2.w * t2.h));
288 (*texture2)[j][i][1] = 0;
289 (*texture2)[j][i][2] = 0;
290 (*texture2)[j][i][3] = 255;
291 }
292 }
293
294 t3.data = LoadRGBImage(TEXTURE_FILE, (GLint *)&t3.w, (GLint *)&t3.h, &t3.format);
295 t3.size = t3.w * t3.h * ((t3.format == GL_RGB) ? 3 : 4);
296 t3.TC = GL_RGBA;
297
298 ReInit(GL_RGBA, Tx = &t1);
299
300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
302 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
303 glEnable(GL_TEXTURE_2D);
304
305 glEnable(GL_BLEND);
306 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
307 }
308
309
310 static void Key( unsigned char key, int x, int y )
311 {
312 (void) x;
313 (void) y;
314 switch (key) {
315 case 27:
316 exit(0);
317 break;
318 case ' ':
319 Anim = !Anim;
320 if (Anim)
321 glutIdleFunc( Idle );
322 else
323 glutIdleFunc( NULL );
324 break;
325 case 't':
326 if (Tx == &t1) {
327 Tx = &t2;
328 } else if (Tx == &t2) {
329 Tx = &t3;
330 } else {
331 Tx = &t1;
332 }
333 ReInit(Tx->TC, Tx);
334 break;
335 case '9':
336 ReInit(GL_RGB, Tx);
337 break;
338 case '0':
339 ReInit(GL_RGBA, Tx);
340 break;
341 case '1':
342 ReInit(GL_COMPRESSED_RGB, Tx);
343 break;
344 case '2':
345 ReInit(GL_COMPRESSED_RGBA, Tx);
346 break;
347 case '3':
348 if (fxt1) ReInit(GL_COMPRESSED_RGB_FXT1_3DFX, Tx);
349 break;
350 case '4':
351 if (fxt1) ReInit(GL_COMPRESSED_RGBA_FXT1_3DFX, Tx);
352 break;
353 case '5':
354 if (dxtc) ReInit(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, Tx);
355 break;
356 case '6':
357 if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, Tx);
358 break;
359 case '7':
360 if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, Tx);
361 break;
362 case '8':
363 if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, Tx);
364 break;
365 case 'a':
366 if (s3tc) ReInit(GL_RGB_S3TC, Tx);
367 break;
368 case 's':
369 if (s3tc) ReInit(GL_RGB4_S3TC, Tx);
370 break;
371 case 'd':
372 if (s3tc) ReInit(GL_RGBA_S3TC, Tx);
373 break;
374 case 'f':
375 if (s3tc) ReInit(GL_RGBA4_S3TC, Tx);
376 break;
377 }
378 glutPostRedisplay();
379 }
380
381
382 int main( int argc, char *argv[] )
383 {
384 float gl_version;
385 GLint num_formats;
386 GLint i;
387 GLint formats[64];
388
389
390 glutInit( &argc, argv );
391 glutInitWindowPosition( 0, 0 );
392 glutInitWindowSize( 400, 300 );
393
394 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
395
396 if (glutCreateWindow(argv[0]) <= 0) {
397 printf("Couldn't create window\n");
398 exit(0);
399 }
400
401 glewInit();
402 gl_version = atof( (const char *) glGetString( GL_VERSION ) );
403 if ( (gl_version < 1.3)
404 && !glutExtensionSupported("GL_ARB_texture_compression") ) {
405 printf("Sorry, GL_ARB_texture_compression not supported\n");
406 exit(0);
407 }
408 if (glutExtensionSupported("GL_3DFX_texture_compression_FXT1")) {
409 fxt1 = GL_TRUE;
410 }
411 if (glutExtensionSupported("GL_EXT_texture_compression_s3tc")) {
412 dxtc = GL_TRUE;
413 }
414 if (glutExtensionSupported("GL_S3_s3tc")) {
415 s3tc = GL_TRUE;
416 }
417
418 glGetIntegerv( GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, & num_formats );
419
420 (void) memset( formats, 0, sizeof( formats ) );
421 glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats );
422
423 printf( "The following texture formats are supported:\n" );
424 for ( i = 0 ; i < num_formats ; i++ ) {
425 printf( "\t%s\n", TextureName( formats[i] ) );
426 }
427
428 Init();
429
430 glutReshapeFunc( Reshape );
431 glutKeyboardFunc( Key );
432 glutDisplayFunc( Display );
433 if (Anim)
434 glutIdleFunc( Idle );
435
436 glutMainLoop();
437 return 0;
438 }