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
);