texcompress2.c revision 32001f49
132001f49Smrg/* 232001f49Smrg * Test texture compression. 332001f49Smrg */ 432001f49Smrg 532001f49Smrg 632001f49Smrg#include <assert.h> 732001f49Smrg#include <stdio.h> 832001f49Smrg#include <GL/glew.h> 932001f49Smrg#include "glut_wrap.h" 1032001f49Smrg#include "readtex.c" 1132001f49Smrg 1232001f49Smrg#define IMAGE_FILE DEMOS_DATA_DIR "arch.rgb" 1332001f49Smrg 1432001f49Smrgstatic int ImgWidth, ImgHeight; 1532001f49Smrgstatic GLenum ImgFormat; 1632001f49Smrgstatic GLenum CompFormat; 1732001f49Smrgstatic GLfloat EyeDist = 5.0; 1832001f49Smrgstatic GLfloat Rot = 0.0; 1932001f49Smrgconst GLenum Target = GL_TEXTURE_2D; 2032001f49Smrg 2132001f49Smrg 2232001f49Smrgstatic void 2332001f49SmrgCheckError(int line) 2432001f49Smrg{ 2532001f49Smrg GLenum err = glGetError(); 2632001f49Smrg if (err) { 2732001f49Smrg printf("GL Error %d at line %d\n", (int) err, line); 2832001f49Smrg } 2932001f49Smrg} 3032001f49Smrg 3132001f49Smrg 3232001f49Smrgstatic const char * 3332001f49SmrgLookupFormat(GLenum format) 3432001f49Smrg{ 3532001f49Smrg switch (format) { 3632001f49Smrg case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 3732001f49Smrg return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; 3832001f49Smrg case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 3932001f49Smrg return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; 4032001f49Smrg case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 4132001f49Smrg return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; 4232001f49Smrg default: 4332001f49Smrg return "other"; 4432001f49Smrg } 4532001f49Smrg} 4632001f49Smrg 4732001f49Smrg 4832001f49Smrgstatic void 4932001f49SmrgTestSubTex(void) 5032001f49Smrg{ 5132001f49Smrg GLboolean all = 0*GL_TRUE; 5232001f49Smrg GLubyte *buffer; 5332001f49Smrg GLint size, fmt; 5432001f49Smrg 5532001f49Smrg glGetTexLevelParameteriv(Target, 0, 5632001f49Smrg GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &size); 5732001f49Smrg glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt); 5832001f49Smrg 5932001f49Smrg buffer = (GLubyte *) malloc(size); 6032001f49Smrg glGetCompressedTexImageARB(Target, 0, buffer); 6132001f49Smrg 6232001f49Smrg printf("Testing sub-texture replacement\n"); 6332001f49Smrg if (all) 6432001f49Smrg glCompressedTexImage2DARB(Target, 0, 6532001f49Smrg fmt, ImgWidth, ImgHeight, 0, 6632001f49Smrg size, buffer); 6732001f49Smrg else { 6832001f49Smrg /* bottom half */ 6932001f49Smrg glCompressedTexSubImage2DARB(Target, 0, 7032001f49Smrg 0, 0, /* pos */ 7132001f49Smrg ImgWidth, ImgHeight / 2, 7232001f49Smrg fmt, size/2, buffer); 7332001f49Smrg /* top half */ 7432001f49Smrg glCompressedTexSubImage2DARB(Target, 0, 7532001f49Smrg 0, ImgHeight / 2, /* pos */ 7632001f49Smrg ImgWidth, ImgHeight / 2, 7732001f49Smrg fmt, size/2, buffer + size / 2); 7832001f49Smrg } 7932001f49Smrg 8032001f49Smrg free(buffer); 8132001f49Smrg} 8232001f49Smrg 8332001f49Smrg 8432001f49Smrgstatic void 8532001f49SmrgTestGetTex(void) 8632001f49Smrg{ 8732001f49Smrg GLubyte *buffer; 8832001f49Smrg 8932001f49Smrg buffer = (GLubyte *) malloc(3 * ImgWidth * ImgHeight); 9032001f49Smrg 9132001f49Smrg glGetTexImage(GL_TEXTURE_2D, 9232001f49Smrg 0, 9332001f49Smrg GL_RGB, 9432001f49Smrg GL_UNSIGNED_BYTE, 9532001f49Smrg buffer); 9632001f49Smrg 9732001f49Smrg free(buffer); 9832001f49Smrg} 9932001f49Smrg 10032001f49Smrg 10132001f49Smrgstatic void 10232001f49SmrgLoadCompressedImage(const char *file) 10332001f49Smrg{ 10432001f49Smrg const GLenum filter = GL_LINEAR; 10532001f49Smrg GLubyte *image; 10632001f49Smrg GLint p; 10732001f49Smrg 10832001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 10932001f49Smrg glPixelStorei(GL_PACK_ALIGNMENT, 1); 11032001f49Smrg 11132001f49Smrg /* 11232001f49Smrg * Load image and scale if needed. 11332001f49Smrg */ 11432001f49Smrg image = LoadRGBImage( file, &ImgWidth, &ImgHeight, &ImgFormat ); 11532001f49Smrg if (!image) { 11632001f49Smrg printf("Couldn't read %s\n", IMAGE_FILE); 11732001f49Smrg exit(0); 11832001f49Smrg } 11932001f49Smrg printf("Image is %d x %d\n", ImgWidth, ImgHeight); 12032001f49Smrg 12132001f49Smrg /* power of two */ 12232001f49Smrg assert(ImgWidth == 128 || ImgWidth == 256 || ImgWidth == 512); 12332001f49Smrg assert(ImgWidth == 128 || ImgHeight == 256 || ImgHeight == 512); 12432001f49Smrg 12532001f49Smrg if (ImgFormat == GL_RGB) 12632001f49Smrg CompFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; 12732001f49Smrg else 12832001f49Smrg CompFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; 12932001f49Smrg 13032001f49Smrg if (ImgFormat == GL_RGBA) { 13132001f49Smrg int i, numAlpha = 0; 13232001f49Smrg for (i = 0; i < ImgWidth * ImgHeight; i++) { 13332001f49Smrg if (image[i*4+3] != 0 && image[i*4+3] != 0xff) { 13432001f49Smrg numAlpha++; 13532001f49Smrg } 13632001f49Smrg if (image[i*4+3] == 0) 13732001f49Smrg image[i*4+3] = 4 * i / ImgWidth; 13832001f49Smrg } 13932001f49Smrg printf("Num Alpha !=0,255: %d\n", numAlpha); 14032001f49Smrg } 14132001f49Smrg 14232001f49Smrg CompFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 14332001f49Smrg 14432001f49Smrg 14532001f49Smrg /* 14632001f49Smrg * Give image to OpenGL and have it compress it. 14732001f49Smrg */ 14832001f49Smrg glTexImage2D(Target, 0, CompFormat, ImgWidth, ImgHeight, 0, 14932001f49Smrg ImgFormat, GL_UNSIGNED_BYTE, image); 15032001f49Smrg CheckError(__LINE__); 15132001f49Smrg 15232001f49Smrg free(image); 15332001f49Smrg 15432001f49Smrg glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, &p); 15532001f49Smrg printf("Compressed Internal Format: %s (0x%x)\n", LookupFormat(p), p); 15632001f49Smrg assert(p == CompFormat); 15732001f49Smrg 15832001f49Smrg printf("Original size: %d bytes\n", ImgWidth * ImgHeight * 3); 15932001f49Smrg glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &p); 16032001f49Smrg printf("Compressed size: %d bytes\n", p); 16132001f49Smrg 16232001f49Smrg glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, filter); 16332001f49Smrg glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, filter); 16432001f49Smrg 16532001f49Smrg if (0) 16632001f49Smrg TestSubTex(); 16732001f49Smrg else 16832001f49Smrg TestGetTex(); 16932001f49Smrg 17032001f49Smrg} 17132001f49Smrg 17232001f49Smrg 17332001f49Smrgstatic void 17432001f49SmrgInit(const char *file) 17532001f49Smrg{ 17632001f49Smrg GLint numFormats, formats[100]; 17732001f49Smrg GLint p; 17832001f49Smrg 17932001f49Smrg if (!glutExtensionSupported("GL_ARB_texture_compression")) { 18032001f49Smrg printf("Sorry, GL_ARB_texture_compression is required.\n"); 18132001f49Smrg exit(1); 18232001f49Smrg } 18332001f49Smrg if (!glutExtensionSupported("GL_EXT_texture_compression_s3tc")) { 18432001f49Smrg printf("Sorry, GL_EXT_texture_compression_s3tc is required.\n"); 18532001f49Smrg exit(1); 18632001f49Smrg } 18732001f49Smrg 18832001f49Smrg printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 18932001f49Smrg printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 19032001f49Smrg 19132001f49Smrg glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &numFormats); 19232001f49Smrg glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats); 19332001f49Smrg printf("%d supported compression formats: ", numFormats); 19432001f49Smrg for (p = 0; p < numFormats; p++) 19532001f49Smrg printf("0x%x ", formats[p]); 19632001f49Smrg printf("\n"); 19732001f49Smrg 19832001f49Smrg LoadCompressedImage(file); 19932001f49Smrg 20032001f49Smrg glEnable(GL_TEXTURE_2D); 20132001f49Smrg 20232001f49Smrg if (ImgFormat == GL_RGBA) { 20332001f49Smrg glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 20432001f49Smrg glEnable(GL_BLEND); 20532001f49Smrg } 20632001f49Smrg} 20732001f49Smrg 20832001f49Smrg 20932001f49Smrgstatic void 21032001f49SmrgReshape( int width, int height ) 21132001f49Smrg{ 21232001f49Smrg glViewport( 0, 0, width, height ); 21332001f49Smrg glMatrixMode( GL_PROJECTION ); 21432001f49Smrg glLoadIdentity(); 21532001f49Smrg glFrustum(-1, 1, -1, 1, 4, 100); 21632001f49Smrg glMatrixMode( GL_MODELVIEW ); 21732001f49Smrg glLoadIdentity(); 21832001f49Smrg} 21932001f49Smrg 22032001f49Smrg 22132001f49Smrgstatic void 22232001f49SmrgKey( unsigned char key, int x, int y ) 22332001f49Smrg{ 22432001f49Smrg (void) x; 22532001f49Smrg (void) y; 22632001f49Smrg switch (key) { 22732001f49Smrg case 'd': 22832001f49Smrg EyeDist -= 1.0; 22932001f49Smrg if (EyeDist < 4.0) 23032001f49Smrg EyeDist = 4.0; 23132001f49Smrg break; 23232001f49Smrg case 'D': 23332001f49Smrg EyeDist += 1.0; 23432001f49Smrg break; 23532001f49Smrg case 'z': 23632001f49Smrg Rot += 5.0; 23732001f49Smrg break; 23832001f49Smrg case 'Z': 23932001f49Smrg Rot -= 5.0; 24032001f49Smrg break; 24132001f49Smrg case 27: 24232001f49Smrg exit(0); 24332001f49Smrg break; 24432001f49Smrg } 24532001f49Smrg glutPostRedisplay(); 24632001f49Smrg} 24732001f49Smrg 24832001f49Smrg 24932001f49Smrgstatic void 25032001f49SmrgDraw( void ) 25132001f49Smrg{ 25232001f49Smrg glClearColor(0.3, 0.3, .8, 0); 25332001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 25432001f49Smrg 25532001f49Smrg glPushMatrix(); 25632001f49Smrg glTranslatef(0, 0, -(EyeDist+0.01)); 25732001f49Smrg glRotatef(Rot, 0, 0, 1); 25832001f49Smrg glBegin(GL_POLYGON); 25932001f49Smrg glTexCoord2f(0, 0); glVertex2f(-1, -1); 26032001f49Smrg glTexCoord2f(1, 0); glVertex2f( 1, -1); 26132001f49Smrg glTexCoord2f(1, 1); glVertex2f( 1, 1); 26232001f49Smrg glTexCoord2f(0, 1); glVertex2f(-1, 1); 26332001f49Smrg glEnd(); 26432001f49Smrg glPopMatrix(); 26532001f49Smrg 26632001f49Smrg glutSwapBuffers(); 26732001f49Smrg} 26832001f49Smrg 26932001f49Smrg 27032001f49Smrgint 27132001f49Smrgmain( int argc, char *argv[] ) 27232001f49Smrg{ 27332001f49Smrg glutInit( &argc, argv ); 27432001f49Smrg glutInitWindowSize( 600, 600 ); 27532001f49Smrg 27632001f49Smrg glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE); 27732001f49Smrg 27832001f49Smrg glutCreateWindow(argv[0]); 27932001f49Smrg glewInit(); 28032001f49Smrg 28132001f49Smrg glutReshapeFunc( Reshape ); 28232001f49Smrg glutKeyboardFunc( Key ); 28332001f49Smrg glutDisplayFunc( Draw ); 28432001f49Smrg 28532001f49Smrg if (argc > 1) 28632001f49Smrg Init(argv[1]); 28732001f49Smrg else 28832001f49Smrg Init(IMAGE_FILE); 28932001f49Smrg 29032001f49Smrg glutMainLoop(); 29132001f49Smrg return 0; 29232001f49Smrg} 293