2
* Compressed texture demo. Written by Daniel Borca.
3
* This program is in the public domain.
10
#define GL_GLEXT_PROTOTYPES 1
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;
33
static TEXTURE *Tx, t1, t2, t3;
34
static GLboolean fxt1, dxtc, s3tc;
37
static const char *TextureName (GLenum TC)
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";
63
return "GL_RGB4_S3TC";
65
return "GL_RGBA_S3TC";
67
return "GL_RGBA4_S3TC";
69
return "Invalid format";
71
return "Unknown format";
77
PrintString(const char *s)
80
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *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 */
94
static void Display( void )
96
/* draw background gradient */
97
glDisable(GL_TEXTURE_2D);
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);
106
glRotatef(Rot, 0, 0, 1);
108
glEnable(GL_TEXTURE_2D);
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);
119
glColor4f(1, 1, 1, 1);
121
glRasterPos3f(-1.2, -0.7, 0);
122
PrintString("Selected: ");
123
PrintString(TextureName(Tx->TC));
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);
139
static void Reshape( int width, int height )
141
glViewport( 0, 0, width, height );
142
glMatrixMode( GL_PROJECTION );
144
glOrtho( -1.5, 1.5, -1.0, 1.0, -1.0, 1.0 );
145
glMatrixMode( GL_MODELVIEW );
150
static void ReInit( GLenum TC, TEXTURE *Tx )
154
if ((Tx->TC == TC) && (Tx->cData != NULL)) {
155
glCompressedTexImage2DARB(GL_TEXTURE_2D, /* target */
157
Tx->cFormat, /* real format */
158
Tx->w, /* original width */
159
Tx->h, /* original height */
161
Tx->cSize, /* compressed size*/
162
Tx->cData); /* compressed data*/
164
glTexImage2D(GL_TEXTURE_2D, /* target */
166
TC, /* internal format */
167
Tx->w, Tx->h, /* width, height */
169
Tx->format, /* texture format */
170
GL_UNSIGNED_BYTE, /* texture type */
171
Tx->data); /* the texture */
173
/* okay, now cache the compressed texture */
175
if (Tx->cData != NULL) {
179
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, &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] = {"\
207
GLubyte (*texture1)[8 * 32][4];
208
GLubyte (*texture2)[256][256][4];
212
t1.size = t1.w * t1.h * 4;
213
t1.data = malloc(t1.size);
217
texture1 = (GLubyte (*)[8 * 32][4])t1.data;
218
for (i = 0; i < sizeof(pattern) - 1; i++) {
219
switch (pattern[i]) {
222
(*texture1)[i][0] = 255;
223
(*texture1)[i][1] = 255;
224
(*texture1)[i][2] = 255;
225
(*texture1)[i][3] = 64;
228
(*texture1)[i][0] = 255;
229
(*texture1)[i][1] = 0;
230
(*texture1)[i][2] = 0;
231
(*texture1)[i][3] = 255;
234
(*texture1)[i][0] = 0;
235
(*texture1)[i][1] = 255;
236
(*texture1)[i][2] = 0;
237
(*texture1)[i][3] = 255;
240
(*texture1)[i][0] = 0;
241
(*texture1)[i][1] = 0;
242
(*texture1)[i][2] = 255;
243
(*texture1)[i][3] = 255;
246
(*texture1)[i][0] = 255;
247
(*texture1)[i][1] = 255;
248
(*texture1)[i][2] = 0;
249
(*texture1)[i][3] = 255;
256
t2.size = t2.w * t2.h * 4;
257
t2.data = malloc(t2.size);
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);
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);
283
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
287
static void Key( unsigned char key, int x, int y )
298
glutIdleFunc( Idle );
300
glutIdleFunc( NULL );
305
} else if (Tx == &t2) {
319
ReInit(GL_COMPRESSED_RGB, Tx);
322
ReInit(GL_COMPRESSED_RGBA, Tx);
325
if (fxt1) ReInit(GL_COMPRESSED_RGB_FXT1_3DFX, Tx);
328
if (fxt1) ReInit(GL_COMPRESSED_RGBA_FXT1_3DFX, Tx);
331
if (dxtc) ReInit(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, Tx);
334
if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, Tx);
337
if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, Tx);
340
if (dxtc) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, Tx);
343
if (s3tc) ReInit(GL_RGB_S3TC, Tx);
346
if (s3tc) ReInit(GL_RGB4_S3TC, Tx);
349
if (s3tc) ReInit(GL_RGBA_S3TC, Tx);
352
if (s3tc) ReInit(GL_RGBA4_S3TC, Tx);
359
int main( int argc, char *argv[] )
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");
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");
384
if (glutExtensionSupported("GL_3DFX_texture_compression_FXT1")) {
387
if (glutExtensionSupported("GL_EXT_texture_compression_s3tc")) {
390
if (glutExtensionSupported("GL_S3_s3tc")) {
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] ) );
406
glutReshapeFunc( Reshape );
407
glutKeyboardFunc( Key );
408
glutDisplayFunc( Display );
410
glutIdleFunc( Idle );