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