1/* 2 * Test texture compression. 3 */ 4 5 6#include <assert.h> 7#include <stdio.h> 8#include <GL/glew.h> 9#include "glut_wrap.h" 10#include "readtex.c" 11 12#define IMAGE_FILE DEMOS_DATA_DIR "arch.rgb" 13 14static int ImgWidth, ImgHeight; 15static GLenum ImgFormat; 16static GLenum CompFormat; 17static GLfloat EyeDist = 5.0; 18static GLfloat Rot = 0.0; 19const GLenum Target = GL_TEXTURE_2D; 20 21 22static void 23CheckError(int line) 24{ 25 GLenum err = glGetError(); 26 if (err) { 27 printf("GL Error %d at line %d\n", (int) err, line); 28 } 29} 30 31 32static const char * 33LookupFormat(GLenum format) 34{ 35 switch (format) { 36 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 37 return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; 38 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 39 return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; 40 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 41 return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; 42 default: 43 return "other"; 44 } 45} 46 47 48static void 49TestSubTex(void) 50{ 51 GLboolean all = 0*GL_TRUE; 52 GLubyte *buffer; 53 GLint size, fmt; 54 55 glGetTexLevelParameteriv(Target, 0, 56 GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &size); 57 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt); 58 59 buffer = (GLubyte *) malloc(size); 60 glGetCompressedTexImageARB(Target, 0, buffer); 61 62 printf("Testing sub-texture replacement\n"); 63 if (all) 64 glCompressedTexImage2DARB(Target, 0, 65 fmt, ImgWidth, ImgHeight, 0, 66 size, buffer); 67 else { 68 /* bottom half */ 69 glCompressedTexSubImage2DARB(Target, 0, 70 0, 0, /* pos */ 71 ImgWidth, ImgHeight / 2, 72 fmt, size/2, buffer); 73 /* top half */ 74 glCompressedTexSubImage2DARB(Target, 0, 75 0, ImgHeight / 2, /* pos */ 76 ImgWidth, ImgHeight / 2, 77 fmt, size/2, buffer + size / 2); 78 } 79 80 free(buffer); 81} 82 83 84static void 85TestGetTex(void) 86{ 87 GLubyte *buffer; 88 89 buffer = (GLubyte *) malloc(3 * ImgWidth * ImgHeight); 90 91 glGetTexImage(GL_TEXTURE_2D, 92 0, 93 GL_RGB, 94 GL_UNSIGNED_BYTE, 95 buffer); 96 97 free(buffer); 98} 99 100 101static void 102LoadCompressedImage(const char *file) 103{ 104 const GLenum filter = GL_LINEAR; 105 GLubyte *image; 106 GLint p; 107 108 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 109 glPixelStorei(GL_PACK_ALIGNMENT, 1); 110 111 /* 112 * Load image and scale if needed. 113 */ 114 image = LoadRGBImage( file, &ImgWidth, &ImgHeight, &ImgFormat ); 115 if (!image) { 116 printf("Couldn't read %s\n", IMAGE_FILE); 117 exit(0); 118 } 119 printf("Image is %d x %d\n", ImgWidth, ImgHeight); 120 121 /* power of two */ 122 assert(ImgWidth == 128 || ImgWidth == 256 || ImgWidth == 512); 123 assert(ImgWidth == 128 || ImgHeight == 256 || ImgHeight == 512); 124 125 if (ImgFormat == GL_RGB) 126 CompFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; 127 else 128 CompFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; 129 130 if (ImgFormat == GL_RGBA) { 131 int i, numAlpha = 0; 132 for (i = 0; i < ImgWidth * ImgHeight; i++) { 133 if (image[i*4+3] != 0 && image[i*4+3] != 0xff) { 134 numAlpha++; 135 } 136 if (image[i*4+3] == 0) 137 image[i*4+3] = 4 * i / ImgWidth; 138 } 139 printf("Num Alpha !=0,255: %d\n", numAlpha); 140 } 141 142 CompFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 143 144 145 /* 146 * Give image to OpenGL and have it compress it. 147 */ 148 glTexImage2D(Target, 0, CompFormat, ImgWidth, ImgHeight, 0, 149 ImgFormat, GL_UNSIGNED_BYTE, image); 150 CheckError(__LINE__); 151 152 free(image); 153 154 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, &p); 155 printf("Compressed Internal Format: %s (0x%x)\n", LookupFormat(p), p); 156 assert(p == CompFormat); 157 158 printf("Original size: %d bytes\n", ImgWidth * ImgHeight * 3); 159 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &p); 160 printf("Compressed size: %d bytes\n", p); 161 162 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, filter); 163 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, filter); 164 165 if (0) 166 TestSubTex(); 167 else 168 TestGetTex(); 169 170} 171 172 173static void 174Init(const char *file) 175{ 176 GLint numFormats, formats[100]; 177 GLint p; 178 179 if (!glutExtensionSupported("GL_ARB_texture_compression")) { 180 printf("Sorry, GL_ARB_texture_compression is required.\n"); 181 exit(1); 182 } 183 if (!glutExtensionSupported("GL_EXT_texture_compression_s3tc")) { 184 printf("Sorry, GL_EXT_texture_compression_s3tc is required.\n"); 185 exit(1); 186 } 187 188 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 189 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 190 191 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &numFormats); 192 glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats); 193 printf("%d supported compression formats: ", numFormats); 194 for (p = 0; p < numFormats; p++) 195 printf("0x%x ", formats[p]); 196 printf("\n"); 197 198 LoadCompressedImage(file); 199 200 glEnable(GL_TEXTURE_2D); 201 202 if (ImgFormat == GL_RGBA) { 203 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 204 glEnable(GL_BLEND); 205 } 206} 207 208 209static void 210Reshape( int width, int height ) 211{ 212 glViewport( 0, 0, width, height ); 213 glMatrixMode( GL_PROJECTION ); 214 glLoadIdentity(); 215 glFrustum(-1, 1, -1, 1, 4, 100); 216 glMatrixMode( GL_MODELVIEW ); 217 glLoadIdentity(); 218} 219 220 221static void 222Key( unsigned char key, int x, int y ) 223{ 224 (void) x; 225 (void) y; 226 switch (key) { 227 case 'd': 228 EyeDist -= 1.0; 229 if (EyeDist < 4.0) 230 EyeDist = 4.0; 231 break; 232 case 'D': 233 EyeDist += 1.0; 234 break; 235 case 'z': 236 Rot += 5.0; 237 break; 238 case 'Z': 239 Rot -= 5.0; 240 break; 241 case 27: 242 exit(0); 243 break; 244 } 245 glutPostRedisplay(); 246} 247 248 249static void 250Draw( void ) 251{ 252 glClearColor(0.3, 0.3, .8, 0); 253 glClear(GL_COLOR_BUFFER_BIT); 254 255 glPushMatrix(); 256 glTranslatef(0, 0, -(EyeDist+0.01)); 257 glRotatef(Rot, 0, 0, 1); 258 glBegin(GL_POLYGON); 259 glTexCoord2f(0, 0); glVertex2f(-1, -1); 260 glTexCoord2f(1, 0); glVertex2f( 1, -1); 261 glTexCoord2f(1, 1); glVertex2f( 1, 1); 262 glTexCoord2f(0, 1); glVertex2f(-1, 1); 263 glEnd(); 264 glPopMatrix(); 265 266 glutSwapBuffers(); 267} 268 269 270int 271main( int argc, char *argv[] ) 272{ 273 glutInit( &argc, argv ); 274 glutInitWindowSize( 600, 600 ); 275 276 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE); 277 278 glutCreateWindow(argv[0]); 279 glewInit(); 280 281 glutReshapeFunc( Reshape ); 282 glutKeyboardFunc( Key ); 283 glutDisplayFunc( Draw ); 284 285 if (argc > 1) 286 Init(argv[1]); 287 else 288 Init(IMAGE_FILE); 289 290 glutMainLoop(); 291 return 0; 292} 293