2 * Compressed texture demo. Written by Daniel Borca.
3 * This program is in the public domain.
10 #include <glad/glad.h>
11 #include "glut_wrap.h"
13 #include "readtex.c" /* I know, this is a hack. */
14 #define TEXTURE_FILE DEMOS_DATA_DIR "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
);
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);
120 glDisable(GL_TEXTURE_2D
);
124 glColor4f(1, 1, 1, 1);
126 glRasterPos3f(-1.2, -0.7, 0);
127 PrintString("Selected: ");
128 PrintString(TextureName(Tx
->TC
));
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
);
144 static void Reshape( int width
, int height
)
146 glViewport( 0, 0, width
, height
);
147 glMatrixMode( GL_PROJECTION
);
149 glOrtho( -1.5, 1.5, -1.0, 1.0, -1.0, 1.0 );
150 glMatrixMode( GL_MODELVIEW
);
155 static void ReInit( GLenum TC
, TEXTURE
*Tx
)
159 if ((Tx
->TC
== TC
) && (Tx
->cData
!= NULL
)) {
160 glCompressedTexImage2DARB(GL_TEXTURE_2D
, /* target */
162 Tx
->cFormat
, /* real format */
163 Tx
->w
, /* original width */
164 Tx
->h
, /* original height */
166 Tx
->cSize
, /* compressed size*/
167 Tx
->cData
); /* compressed data*/
169 glTexImage2D(GL_TEXTURE_2D
, /* target */
171 TC
, /* internal format */
172 Tx
->w
, Tx
->h
, /* width, height */
174 Tx
->format
, /* texture format */
175 GL_UNSIGNED_BYTE
, /* texture type */
176 Tx
->data
); /* the texture */
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
);
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",
196 /* okay, now cache the compressed texture */
198 if (Tx
->cData
!= NULL
) {
202 glGetTexLevelParameteriv(GL_TEXTURE_2D
, 0, GL_TEXTURE_COMPRESSED_ARB
, &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
);
214 static void Init( void )
216 /* HEIGHT * WIDTH + 1 (for trailing '\0') */
217 static char pattern
[8 * 32 + 1] = {"\
230 GLubyte (*texture1
)[8 * 32][4];
231 GLubyte (*texture2
)[256][256][4];
235 t1
.size
= t1
.w
* t1
.h
* 4;
236 t1
.data
= malloc(t1
.size
);
240 texture1
= (GLubyte (*)[8 * 32][4])t1
.data
;
241 for (i
= 0; i
< sizeof(pattern
) - 1; i
++) {
242 switch (pattern
[i
]) {
245 (*texture1
)[i
][0] = 255;
246 (*texture1
)[i
][1] = 255;
247 (*texture1
)[i
][2] = 255;
248 (*texture1
)[i
][3] = 64;
251 (*texture1
)[i
][0] = 255;
252 (*texture1
)[i
][1] = 0;
253 (*texture1
)[i
][2] = 0;
254 (*texture1
)[i
][3] = 255;
257 (*texture1
)[i
][0] = 0;
258 (*texture1
)[i
][1] = 255;
259 (*texture1
)[i
][2] = 0;
260 (*texture1
)[i
][3] = 255;
263 (*texture1
)[i
][0] = 0;
264 (*texture1
)[i
][1] = 0;
265 (*texture1
)[i
][2] = 255;
266 (*texture1
)[i
][3] = 255;
269 (*texture1
)[i
][0] = 255;
270 (*texture1
)[i
][1] = 255;
271 (*texture1
)[i
][2] = 0;
272 (*texture1
)[i
][3] = 255;
279 t2
.size
= t2
.w
* t2
.h
* 4;
280 t2
.data
= malloc(t2
.size
);
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;
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);
298 ReInit(GL_RGBA
, Tx
= &t1
);
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
);
306 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
310 static void Key( unsigned char key
, int x
, int y
)
321 glutIdleFunc( Idle
);
323 glutIdleFunc( NULL
);
328 } else if (Tx
== &t2
) {
342 ReInit(GL_COMPRESSED_RGB
, Tx
);
345 ReInit(GL_COMPRESSED_RGBA
, Tx
);
348 if (fxt1
) ReInit(GL_COMPRESSED_RGB_FXT1_3DFX
, Tx
);
351 if (fxt1
) ReInit(GL_COMPRESSED_RGBA_FXT1_3DFX
, Tx
);
354 if (dxtc
) ReInit(GL_COMPRESSED_RGB_S3TC_DXT1_EXT
, Tx
);
357 if (dxtc
) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
, Tx
);
360 if (dxtc
) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
, Tx
);
363 if (dxtc
) ReInit(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
, Tx
);
366 if (s3tc
) ReInit(GL_RGB_S3TC
, Tx
);
369 if (s3tc
) ReInit(GL_RGB4_S3TC
, Tx
);
372 if (s3tc
) ReInit(GL_RGBA_S3TC
, Tx
);
375 if (s3tc
) ReInit(GL_RGBA4_S3TC
, Tx
);
382 int main( int argc
, char *argv
[] )
390 glutInit( &argc
, argv
);
391 glutInitWindowPosition( 0, 0 );
392 glutInitWindowSize( 400, 300 );
394 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
396 if (glutCreateWindow(argv
[0]) <= 0) {
397 printf("Couldn't create window\n");
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");
408 if (glutExtensionSupported("GL_3DFX_texture_compression_FXT1")) {
411 if (glutExtensionSupported("GL_EXT_texture_compression_s3tc")) {
414 if (glutExtensionSupported("GL_S3_s3tc")) {
418 glGetIntegerv( GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB
, & num_formats
);
420 (void) memset( formats
, 0, sizeof( formats
) );
421 glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS_ARB
, formats
);
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
] ) );
430 glutReshapeFunc( Reshape
);
431 glutKeyboardFunc( Key
);
432 glutDisplayFunc( Display
);
434 glutIdleFunc( Idle
);