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