Convert libGL and DRI drivers to require libdrm.
[mesa-demos.git] / src / tests / texcmp.c
blob6e822fb6895f49abdf45773f71ec33cd517edb1a
1 /*
2 * Compressed texture demo. Written by Daniel Borca.
3 * This program is in the public domain.
4 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <math.h>
9 #include <string.h>
10 #define GL_GLEXT_PROTOTYPES 1
11 #include <GL/glut.h>
13 #include "readtex.c" /* I know, this is a hack. */
14 #define TEXTURE_FILE "../images/tree2.rgba"
17 static float Rot = 0.0;
18 static GLboolean Anim = 1;
20 typedef struct {
21 GLubyte *data;
22 GLuint size;
23 GLenum format;
24 GLuint w, h;
26 GLenum TC;
28 GLubyte *cData;
29 GLuint cSize;
30 GLenum cFormat;
31 } TEXTURE;
33 static TEXTURE *Tx, t1, t2, t3;
34 static GLboolean fxt1, dxtc, s3tc;
37 static const char *TextureName (GLenum TC)
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";
76 static void
77 PrintString(const char *s)
79 while (*s) {
80 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
81 s++;
86 static void Idle( void )
88 float t = glutGet(GLUT_ELAPSED_TIME) * 0.001; /* in seconds */
89 Rot = t * 360 / 4; /* 1 rotation per 4 seconds */
90 glutPostRedisplay();
94 static void Display( void )
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();
105 glPushMatrix();
106 glRotatef(Rot, 0, 0, 1);
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();
116 glPopMatrix();
118 /* info */
119 glColor4f(1, 1, 1, 1);
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);
135 glutSwapBuffers();
139 static void Reshape( int width, int height )
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();
150 static void ReInit( GLenum TC, TEXTURE *Tx )
152 GLint rv;
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 */
173 /* okay, now cache the compressed texture */
174 Tx->TC = TC;
175 if (Tx->cData != NULL) {
176 free(Tx->cData);
177 Tx->cData = NULL;
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);
191 static void Init( void )
193 /* HEIGHT * WIDTH + 1 (for trailing '\0') */
194 static char pattern[8 * 32 + 1] = {"\
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 \
205 GLuint i, j;
207 GLubyte (*texture1)[8 * 32][4];
208 GLubyte (*texture2)[256][256][4];
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;
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;
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;
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;
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;
275 ReInit(GL_RGBA, Tx = &t1);
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);
282 glEnable(GL_BLEND);
283 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
287 static void Key( unsigned char key, int x, int y )
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;
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;
355 glutPostRedisplay();
359 int main( int argc, char *argv[] )
361 float gl_version;
362 GLint num_formats;
363 GLint i;
364 GLint formats[64];
367 glutInit( &argc, argv );
368 glutInitWindowPosition( 0, 0 );
369 glutInitWindowSize( 400, 300 );
371 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
373 if (glutCreateWindow(argv[0]) <= 0) {
374 printf("Couldn't create window\n");
375 exit(0);
378 gl_version = atof( (const char *) glGetString( GL_VERSION ) );
379 if ( (gl_version < 1.3)
380 && !glutExtensionSupported("GL_ARB_texture_compression") ) {
381 printf("Sorry, GL_ARB_texture_compression not supported\n");
382 exit(0);
384 if (glutExtensionSupported("GL_3DFX_texture_compression_FXT1")) {
385 fxt1 = GL_TRUE;
387 if (glutExtensionSupported("GL_EXT_texture_compression_s3tc")) {
388 dxtc = GL_TRUE;
390 if (glutExtensionSupported("GL_S3_s3tc")) {
391 s3tc = GL_TRUE;
394 glGetIntegerv( GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, & num_formats );
396 (void) memset( formats, 0, sizeof( formats ) );
397 glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats );
399 printf( "The following texture formats are supported:\n" );
400 for ( i = 0 ; i < num_formats ; i++ ) {
401 printf( "\t%s\n", TextureName( formats[i] ) );
404 Init();
406 glutReshapeFunc( Reshape );
407 glutKeyboardFunc( Key );
408 glutDisplayFunc( Display );
409 if (Anim)
410 glutIdleFunc( Idle );
412 glutMainLoop();
413 return 0;