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