From aecd02b391c6719210d14ae10dbeb064fb2359eb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 10 May 2006 22:47:06 +0000 Subject: [PATCH] simple texture compression test --- progs/tests/Makefile | 1 + progs/tests/texcompress2.c | 273 +++++++++++++++++++++++++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 progs/tests/texcompress2.c diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 79eaf6f31e9..7f6655dd54b 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -58,6 +58,7 @@ SOURCES = \ stencil_wrap.c \ subtexrate.c \ tex1d.c \ + texcompress2.c \ texfilt.c \ texline.c \ texobjshare.c \ diff --git a/progs/tests/texcompress2.c b/progs/tests/texcompress2.c new file mode 100644 index 00000000000..e2eed756b62 --- /dev/null +++ b/progs/tests/texcompress2.c @@ -0,0 +1,273 @@ +/* + * Test texture compression. + */ + + +#define GL_GLEXT_PROTOTYPES +#include +#include +#include +#include +#include "readtex.c" + +#define IMAGE_FILE "../images/arch.rgb" + +static int ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLenum CompFormat; +static GLfloat EyeDist = 5.0; +static GLfloat Rot = 0.0; +const GLenum Target = GL_TEXTURE_2D; + + +static void +CheckError(int line) +{ + GLenum err = glGetError(); + if (err) { + printf("GL Error %d at line %d\n", (int) err, line); + } +} + + +static const char * +LookupFormat(GLenum format) +{ + switch (format) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; + default: + return "other"; + } +} + + +static void +TestSubTex(void) +{ + GLboolean all = 0*GL_TRUE; + GLubyte *buffer; + GLint size, fmt; + int i; + + glGetTexLevelParameteriv(Target, 0, + GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &size); + glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt); + + buffer = (GLubyte *) malloc(size); + glGetCompressedTexImageARB(Target, 0, buffer); + + printf("Testing sub-texture replacement\n"); + if (all) + glCompressedTexImage2DARB(Target, 0, + fmt, ImgWidth, ImgHeight, 0, + size, buffer); + else { + /* bottom half */ + glCompressedTexSubImage2DARB(Target, 0, + 0, 0, /* pos */ + ImgWidth, ImgHeight / 2, + fmt, size/2, buffer); + /* top half */ + glCompressedTexSubImage2DARB(Target, 0, + 0, ImgHeight / 2, /* pos */ + ImgWidth, ImgHeight / 2, + fmt, size/2, buffer + size / 2); + } + + free(buffer); +} + + +static void +LoadCompressedImage(const char *file) +{ + const GLenum filter = GL_LINEAR; + GLubyte *image; + GLint p; + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + /* + * Load image and scale if needed. + */ + image = LoadRGBImage( file, &ImgWidth, &ImgHeight, &ImgFormat ); + if (!image) { + printf("Couldn't read %s\n", IMAGE_FILE); + exit(0); + } + printf("Image is %d x %d\n", ImgWidth, ImgHeight); + + /* power of two */ + assert(ImgWidth == 128 || ImgWidth == 256 || ImgWidth == 512); + assert(ImgWidth == 128 || ImgHeight == 256 || ImgHeight == 512); + + if (ImgFormat == GL_RGB) + CompFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + else + CompFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + + if (ImgFormat == GL_RGBA) { + int i, numAlpha = 0; + for (i = 0; i < ImgWidth * ImgHeight; i++) { + if (image[i*4+3] != 0 && image[i*4+3] != 0xff) { + numAlpha++; + } + if (image[i*4+3] == 0) + image[i*4+3] = 4 * i / ImgWidth; + } + printf("Num Alpha !=0,255: %d\n", numAlpha); + } + + CompFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + + + /* + * Give image to OpenGL and have it compress it. + */ + glTexImage2D(Target, 0, CompFormat, ImgWidth, ImgHeight, 0, + ImgFormat, GL_UNSIGNED_BYTE, image); + CheckError(__LINE__); + + free(image); + + glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, &p); + printf("Compressed Internal Format: %s (0x%x)\n", LookupFormat(p), p); + assert(p == CompFormat); + + printf("Original size: %d bytes\n", ImgWidth * ImgHeight * 3); + glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &p); + printf("Compressed size: %d bytes\n", p); + + glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, filter); + + TestSubTex(); + +} + + +static void +Init(const char *file) +{ + GLint numFormats, formats[100]; + GLint p; + + if (!glutExtensionSupported("GL_ARB_texture_compression")) { + printf("Sorry, GL_ARB_texture_compression is required.\n"); + exit(1); + } + if (!glutExtensionSupported("GL_EXT_texture_compression_s3tc")) { + printf("Sorry, GL_EXT_texture_compression_s3tc is required.\n"); + exit(1); + } + + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &numFormats); + glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats); + printf("%d supported compression formats: ", numFormats); + for (p = 0; p < numFormats; p++) + printf("0x%x ", formats[p]); + printf("\n"); + + LoadCompressedImage(file); + + glEnable(GL_TEXTURE_2D); + + if (ImgFormat == GL_RGBA) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } +} + + +static void +Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum(-1, 1, -1, 1, 4, 100); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); +} + + +static void +Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 'd': + EyeDist -= 1.0; + if (EyeDist < 4.0) + EyeDist = 4.0; + break; + case 'D': + EyeDist += 1.0; + break; + case 'z': + Rot += 5.0; + break; + case 'Z': + Rot -= 5.0; + break; + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +Draw( void ) +{ + glClearColor(0.3, 0.3, .8, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(0, 0, -(EyeDist+0.01)); + glRotatef(Rot, 0, 0, 1); + glBegin(GL_POLYGON); + glTexCoord2f(0, 0); glVertex2f(-1, -1); + glTexCoord2f(1, 0); glVertex2f( 1, -1); + glTexCoord2f(1, 1); glVertex2f( 1, 1); + glTexCoord2f(0, 1); glVertex2f(-1, 1); + glEnd(); + glPopMatrix(); + + glutSwapBuffers(); +} + + +int +main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowSize( 600, 600 ); + + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE); + + glutCreateWindow(argv[0]); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutDisplayFunc( Draw ); + + if (argc > 1) + Init(argv[1]); + else + Init(IMAGE_FILE); + + glutMainLoop(); + return 0; +} -- 2.30.2