blob: cbb8f1d3a22d53b783dbd264d80483c1b9f88da6 [file] [log] [blame]
Brian Paulaecd02b2006-05-10 22:47:06 +00001/*
2 * Test texture compression.
3 */
4
5
Brian Paulaecd02b2006-05-10 22:47:06 +00006#include <assert.h>
7#include <stdio.h>
Keith Whitwella58065d2009-03-10 13:11:23 +00008#include <GL/glew.h>
Brian Paulaecd02b2006-05-10 22:47:06 +00009#include <GL/glut.h>
Brian Paulaecd02b2006-05-10 22:47:06 +000010#include "readtex.c"
11
12#define IMAGE_FILE "../images/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 int i;
55
56 glGetTexLevelParameteriv(Target, 0,
57 GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &size);
58 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
59
60 buffer = (GLubyte *) malloc(size);
61 glGetCompressedTexImageARB(Target, 0, buffer);
62
63 printf("Testing sub-texture replacement\n");
64 if (all)
65 glCompressedTexImage2DARB(Target, 0,
66 fmt, ImgWidth, ImgHeight, 0,
67 size, buffer);
68 else {
69 /* bottom half */
70 glCompressedTexSubImage2DARB(Target, 0,
71 0, 0, /* pos */
72 ImgWidth, ImgHeight / 2,
73 fmt, size/2, buffer);
74 /* top half */
75 glCompressedTexSubImage2DARB(Target, 0,
76 0, ImgHeight / 2, /* pos */
77 ImgWidth, ImgHeight / 2,
78 fmt, size/2, buffer + size / 2);
79 }
80
81 free(buffer);
82}
83
84
85static void
86LoadCompressedImage(const char *file)
87{
88 const GLenum filter = GL_LINEAR;
89 GLubyte *image;
90 GLint p;
91
92 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
93 glPixelStorei(GL_PACK_ALIGNMENT, 1);
94
95 /*
96 * Load image and scale if needed.
97 */
98 image = LoadRGBImage( file, &ImgWidth, &ImgHeight, &ImgFormat );
99 if (!image) {
100 printf("Couldn't read %s\n", IMAGE_FILE);
101 exit(0);
102 }
103 printf("Image is %d x %d\n", ImgWidth, ImgHeight);
104
105 /* power of two */
106 assert(ImgWidth == 128 || ImgWidth == 256 || ImgWidth == 512);
107 assert(ImgWidth == 128 || ImgHeight == 256 || ImgHeight == 512);
108
109 if (ImgFormat == GL_RGB)
110 CompFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
111 else
112 CompFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
113
114 if (ImgFormat == GL_RGBA) {
115 int i, numAlpha = 0;
116 for (i = 0; i < ImgWidth * ImgHeight; i++) {
117 if (image[i*4+3] != 0 && image[i*4+3] != 0xff) {
118 numAlpha++;
119 }
120 if (image[i*4+3] == 0)
121 image[i*4+3] = 4 * i / ImgWidth;
122 }
123 printf("Num Alpha !=0,255: %d\n", numAlpha);
124 }
125
126 CompFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
127
128
129 /*
130 * Give image to OpenGL and have it compress it.
131 */
132 glTexImage2D(Target, 0, CompFormat, ImgWidth, ImgHeight, 0,
133 ImgFormat, GL_UNSIGNED_BYTE, image);
134 CheckError(__LINE__);
135
136 free(image);
137
138 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, &p);
139 printf("Compressed Internal Format: %s (0x%x)\n", LookupFormat(p), p);
140 assert(p == CompFormat);
141
142 printf("Original size: %d bytes\n", ImgWidth * ImgHeight * 3);
143 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &p);
144 printf("Compressed size: %d bytes\n", p);
145
146 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, filter);
147 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, filter);
148
149 TestSubTex();
150
151}
152
153
154static void
155Init(const char *file)
156{
157 GLint numFormats, formats[100];
158 GLint p;
159
160 if (!glutExtensionSupported("GL_ARB_texture_compression")) {
161 printf("Sorry, GL_ARB_texture_compression is required.\n");
162 exit(1);
163 }
164 if (!glutExtensionSupported("GL_EXT_texture_compression_s3tc")) {
165 printf("Sorry, GL_EXT_texture_compression_s3tc is required.\n");
166 exit(1);
167 }
168
169 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
170 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
171
172 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &numFormats);
173 glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats);
174 printf("%d supported compression formats: ", numFormats);
175 for (p = 0; p < numFormats; p++)
176 printf("0x%x ", formats[p]);
177 printf("\n");
178
179 LoadCompressedImage(file);
180
181 glEnable(GL_TEXTURE_2D);
182
183 if (ImgFormat == GL_RGBA) {
184 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
185 glEnable(GL_BLEND);
186 }
187}
188
189
190static void
191Reshape( int width, int height )
192{
193 glViewport( 0, 0, width, height );
194 glMatrixMode( GL_PROJECTION );
195 glLoadIdentity();
196 glFrustum(-1, 1, -1, 1, 4, 100);
197 glMatrixMode( GL_MODELVIEW );
198 glLoadIdentity();
199}
200
201
202static void
203Key( unsigned char key, int x, int y )
204{
205 (void) x;
206 (void) y;
207 switch (key) {
208 case 'd':
209 EyeDist -= 1.0;
210 if (EyeDist < 4.0)
211 EyeDist = 4.0;
212 break;
213 case 'D':
214 EyeDist += 1.0;
215 break;
216 case 'z':
217 Rot += 5.0;
218 break;
219 case 'Z':
220 Rot -= 5.0;
221 break;
222 case 27:
223 exit(0);
224 break;
225 }
226 glutPostRedisplay();
227}
228
229
230static void
231Draw( void )
232{
233 glClearColor(0.3, 0.3, .8, 0);
234 glClear(GL_COLOR_BUFFER_BIT);
235
236 glPushMatrix();
237 glTranslatef(0, 0, -(EyeDist+0.01));
238 glRotatef(Rot, 0, 0, 1);
239 glBegin(GL_POLYGON);
240 glTexCoord2f(0, 0); glVertex2f(-1, -1);
241 glTexCoord2f(1, 0); glVertex2f( 1, -1);
242 glTexCoord2f(1, 1); glVertex2f( 1, 1);
243 glTexCoord2f(0, 1); glVertex2f(-1, 1);
244 glEnd();
245 glPopMatrix();
246
247 glutSwapBuffers();
248}
249
250
251int
252main( int argc, char *argv[] )
253{
254 glutInit( &argc, argv );
255 glutInitWindowSize( 600, 600 );
256
257 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE);
258
259 glutCreateWindow(argv[0]);
Keith Whitwella58065d2009-03-10 13:11:23 +0000260 glewInit();
Brian Paulaecd02b2006-05-10 22:47:06 +0000261
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}