test_texcomp

annotate main.c @ 2:31d30a9c4491

more compressed format strings
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 09 Jan 2018 08:45:44 +0200
parents ed40258af7ad
children
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@0 2 #include <stdlib.h>
nuclear@0 3 #include <string.h>
nuclear@0 4 #include <errno.h>
nuclear@0 5 #include <assert.h>
nuclear@0 6 #include <GL/freeglut.h>
nuclear@0 7
nuclear@0 8 #undef USE_SRGB
nuclear@0 9
nuclear@0 10 #ifdef USE_SRGB
nuclear@0 11 #define COMP_FMT GL_COMPRESSED_SRGB8_ETC2
nuclear@0 12 #else
nuclear@0 13 #define COMP_FMT GL_COMPRESSED_RGB8_ETC2
nuclear@0 14 #endif
nuclear@0 15
nuclear@0 16 int init(void);
nuclear@0 17 int texcomp(unsigned char *compix, unsigned int tofmt, unsigned char *pixels,
nuclear@0 18 int xsz, int ysz, unsigned int fromfmt, unsigned int fromtype);
nuclear@0 19 void disp(void);
nuclear@0 20 void reshape(int x, int y);
nuclear@0 21 void keyb(unsigned char key, int x, int y);
nuclear@0 22 void gen_image(unsigned char *pixels, int xsz, int ysz);
nuclear@1 23 unsigned char *load_compressed_image(const char *fname, int *cszptr, int *xszptr, int *yszptr);
nuclear@1 24 int dump_compressed_image(const char *fname, unsigned char *data, int size, int w, int h);
nuclear@1 25 void print_compressed_formats(void);
nuclear@0 26
nuclear@0 27 unsigned int tex, comp_tex;
nuclear@0 28 const char *texfile;
nuclear@0 29
nuclear@0 30 int main(int argc, char **argv)
nuclear@0 31 {
nuclear@0 32 unsigned int glut_flags = GLUT_RGB | GLUT_DOUBLE;
nuclear@0 33 #ifdef USE_SRGB
nuclear@0 34 glut_flags |= GLUT_SRGB;
nuclear@0 35 #endif
nuclear@0 36
nuclear@0 37 texfile = argv[1];
nuclear@0 38
nuclear@0 39 glutInit(&argc, argv);
nuclear@0 40 glutInitWindowSize(800, 600);
nuclear@0 41 glutInitDisplayMode(glut_flags);
nuclear@0 42 glutCreateWindow("test");
nuclear@0 43
nuclear@0 44 glutDisplayFunc(disp);
nuclear@0 45 glutReshapeFunc(reshape);
nuclear@0 46 glutKeyboardFunc(keyb);
nuclear@0 47
nuclear@0 48 if(init() == -1) {
nuclear@0 49 return 1;
nuclear@0 50 }
nuclear@0 51
nuclear@0 52 glutMainLoop();
nuclear@0 53 return 0;
nuclear@0 54 }
nuclear@0 55
nuclear@0 56 int init(void)
nuclear@0 57 {
nuclear@0 58 unsigned char *pixels, *buf;
nuclear@0 59 int xsz = 512;
nuclear@0 60 int ysz = 512;
nuclear@0 61 int is_comp = 0;
nuclear@0 62 int comp_size = 0;
nuclear@1 63 int tmp;
nuclear@1 64
nuclear@1 65 print_compressed_formats();
nuclear@0 66
nuclear@0 67 if(texfile) {
nuclear@1 68 if(!(pixels = load_compressed_image(texfile, &comp_size, &xsz, &ysz))) {
nuclear@0 69 return -1;
nuclear@0 70 }
nuclear@0 71 printf("loaded compressed texture file: %s (%dx%d)\n", texfile, xsz, ysz);
nuclear@0 72
nuclear@0 73 } else {
nuclear@0 74 if(!(pixels = malloc(xsz * ysz * 3))) {
nuclear@0 75 abort();
nuclear@0 76 }
nuclear@0 77 gen_image(pixels, xsz, ysz);
nuclear@0 78
nuclear@0 79 printf("compressing texture\n");
nuclear@0 80 if((comp_size = texcomp(pixels, COMP_FMT, pixels, xsz, ysz, GL_RGB, GL_UNSIGNED_BYTE)) == -1) {
nuclear@0 81 return -1;
nuclear@0 82 }
nuclear@0 83 printf("compressed texture is %d bytes (uncompressed was: %d)\n", comp_size, xsz * ysz * 3);
nuclear@0 84
nuclear@1 85 dump_compressed_image("compressed_texture", pixels, comp_size, xsz, ysz);
nuclear@0 86 }
nuclear@0 87
nuclear@0 88 glGenTextures(1, &tex);
nuclear@0 89 glBindTexture(GL_TEXTURE_2D, tex);
nuclear@0 90 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@0 91 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@0 92 glCompressedTexImage2D(GL_TEXTURE_2D, 0, COMP_FMT, xsz, ysz, 0, comp_size, pixels);
nuclear@0 93 if(glGetError()) {
nuclear@0 94 fprintf(stderr, "failed to upload compressed texture\n");
nuclear@0 95 return -1;
nuclear@0 96 }
nuclear@0 97
nuclear@0 98 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_comp);
nuclear@0 99 if(!is_comp) {
nuclear@0 100 fprintf(stderr, "texture is not compressed\n");
nuclear@0 101 return -1;
nuclear@0 102 }
nuclear@0 103 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &tmp);
nuclear@0 104 if(tmp != comp_size) {
nuclear@0 105 fprintf(stderr, "internal compressed size differs (expected: %d, got: %d)!\n", comp_size, tmp);
nuclear@0 106 return -1;
nuclear@0 107 }
nuclear@0 108
nuclear@0 109 if(!(buf = malloc(comp_size))) {
nuclear@0 110 fprintf(stderr, "failed to allocate comparison image buffer (%d bytes)\n", comp_size);
nuclear@0 111 return -1;
nuclear@0 112 }
nuclear@0 113 glGetCompressedTexImage(GL_TEXTURE_2D, 0, buf);
nuclear@0 114
nuclear@0 115 if(memcmp(pixels, buf, comp_size) != 0) {
nuclear@0 116 fprintf(stderr, "submitted and retrieved pixel data differ!\n");
nuclear@1 117 } else {
nuclear@1 118 printf("submitted and retrieved sizes match (%d bytes)\n", comp_size);
nuclear@0 119 }
nuclear@0 120 free(buf);
nuclear@0 121 free(pixels);
nuclear@0 122
nuclear@0 123 #ifdef USE_SRGB
nuclear@0 124 glEnable(GL_FRAMEBUFFER_SRGB);
nuclear@0 125 #endif
nuclear@0 126
nuclear@0 127 glEnable(GL_TEXTURE_2D);
nuclear@0 128 return 0;
nuclear@0 129 }
nuclear@0 130
nuclear@0 131 int texcomp(unsigned char *compix, unsigned int tofmt, unsigned char *pixels,
nuclear@0 132 int xsz, int ysz, unsigned int fromfmt, unsigned int fromtype)
nuclear@0 133 {
nuclear@0 134 unsigned int tex;
nuclear@0 135 int is_comp = 0;
nuclear@0 136 int comp_size = 0;
nuclear@0 137
nuclear@0 138 glGenTextures(1, &tex);
nuclear@0 139 glBindTexture(GL_TEXTURE_2D, tex);
nuclear@0 140 glTexImage2D(GL_TEXTURE_2D, 0, tofmt, xsz, ysz, 0, fromfmt, fromtype, pixels);
nuclear@0 141 if(glGetError()) {
nuclear@0 142 fprintf(stderr, "failed to compress texture\n");
nuclear@0 143 return -1;
nuclear@0 144 }
nuclear@0 145
nuclear@0 146 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_comp);
nuclear@0 147 if(!is_comp) {
nuclear@0 148 fprintf(stderr, "texture is not compressed\n");
nuclear@0 149 return -1;
nuclear@0 150 }
nuclear@0 151 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &comp_size);
nuclear@0 152
nuclear@0 153 glGetCompressedTexImage(GL_TEXTURE_2D, 0, compix);
nuclear@0 154 return comp_size;
nuclear@0 155 }
nuclear@0 156
nuclear@0 157 void disp(void)
nuclear@0 158 {
nuclear@0 159 glClear(GL_COLOR_BUFFER_BIT);
nuclear@0 160
nuclear@0 161 glBegin(GL_QUADS);
nuclear@0 162 glTexCoord2f(0, 1); glVertex2f(-1, -1);
nuclear@0 163 glTexCoord2f(1, 1); glVertex2f(1, -1);
nuclear@0 164 glTexCoord2f(1, 0); glVertex2f(1, 1);
nuclear@0 165 glTexCoord2f(0, 0); glVertex2f(-1, 1);
nuclear@0 166 glEnd();
nuclear@0 167
nuclear@0 168 glutSwapBuffers();
nuclear@0 169 assert(glGetError() == GL_NO_ERROR);
nuclear@0 170 }
nuclear@0 171
nuclear@0 172 void reshape(int x, int y)
nuclear@0 173 {
nuclear@0 174 float aspect = (float)x / (float)y;
nuclear@0 175 glViewport(0, 0, x, y);
nuclear@0 176
nuclear@0 177 glMatrixMode(GL_PROJECTION);
nuclear@0 178 glLoadIdentity();
nuclear@0 179 glScalef(1.0 / aspect, 1, 1);
nuclear@0 180 }
nuclear@0 181
nuclear@0 182 void keyb(unsigned char key, int x, int y)
nuclear@0 183 {
nuclear@0 184 if(key == 27) {
nuclear@0 185 exit(0);
nuclear@0 186 }
nuclear@0 187 }
nuclear@0 188
nuclear@0 189 void gen_image(unsigned char *pixels, int xsz, int ysz)
nuclear@0 190 {
nuclear@0 191 int i, j;
nuclear@0 192
nuclear@0 193 for(i=0; i<ysz; i++) {
nuclear@0 194 for(j=0; j<xsz; j++) {
nuclear@0 195 int xor = i ^ j;
nuclear@0 196
nuclear@0 197 *pixels++ = xor & 0xff;
nuclear@0 198 *pixels++ = (xor << 1) & 0xff;
nuclear@0 199 *pixels++ = (xor << 2) & 0xff;
nuclear@0 200 }
nuclear@0 201 }
nuclear@0 202 }
nuclear@1 203
nuclear@1 204 unsigned char *load_compressed_image(const char *fname, int *cszptr, int *xszptr, int *yszptr)
nuclear@1 205 {
nuclear@1 206 unsigned char *pixels;
nuclear@1 207 long start, comp_size;
nuclear@1 208 int xsz, ysz;
nuclear@1 209 FILE *fp;
nuclear@1 210
nuclear@1 211 if(!(fp = fopen(texfile, "rb"))) {
nuclear@1 212 fprintf(stderr, "failed to open compressed texture file: %s: %s\n", texfile, strerror(errno));
nuclear@1 213 return 0;
nuclear@1 214 }
nuclear@1 215
nuclear@1 216 if(fread(&xsz, sizeof xsz, 1, fp) < 1 || fread(&ysz, sizeof ysz, 1, fp) < 1) {
nuclear@1 217 fprintf(stderr, "failed to read compressed texture file header: %s: %s\n", texfile, strerror(errno));
nuclear@1 218 fclose(fp);
nuclear@1 219 return 0;
nuclear@1 220 }
nuclear@1 221 start = ftell(fp);
nuclear@1 222 fseek(fp, 0, SEEK_END);
nuclear@1 223 comp_size = ftell(fp) - start;
nuclear@1 224 fseek(fp, start, SEEK_SET);
nuclear@1 225
nuclear@1 226 if(!(pixels = malloc(comp_size))) {
nuclear@1 227 perror("failed to allocate pixel buffer");
nuclear@1 228 return 0;
nuclear@1 229 }
nuclear@1 230 if(fread(pixels, 1, comp_size, fp) < comp_size) {
nuclear@1 231 fprintf(stderr, "failed to read compressed texture file: %s: %s\n", texfile, strerror(errno));
nuclear@1 232 fclose(fp);
nuclear@1 233 free(pixels);
nuclear@1 234 return 0;
nuclear@1 235 }
nuclear@1 236 fclose(fp);
nuclear@1 237
nuclear@1 238 *cszptr = comp_size;
nuclear@1 239 *xszptr = xsz;
nuclear@1 240 *yszptr = ysz;
nuclear@1 241 return pixels;
nuclear@1 242 }
nuclear@1 243
nuclear@1 244 int dump_compressed_image(const char *fname, unsigned char *data, int size, int w, int h)
nuclear@1 245 {
nuclear@1 246 FILE *fp;
nuclear@1 247
nuclear@1 248 if(!(fp = fopen(fname, "wb"))) {
nuclear@1 249 fprintf(stderr, "failed to open compressed texture dump file: %s: %s\n", fname, strerror(errno));
nuclear@1 250 return -1;
nuclear@1 251 }
nuclear@1 252
nuclear@1 253 if(fwrite(&w, sizeof w, 1, fp) < 1 ||
nuclear@1 254 fwrite(&h, sizeof h, 1, fp) < 1 ||
nuclear@1 255 fwrite(data, 1, size, fp) < size) {
nuclear@1 256 fprintf(stderr, "failed to dump compressed texture: %s\n", strerror(errno));
nuclear@1 257 }
nuclear@1 258 fclose(fp);
nuclear@1 259 return 0;
nuclear@1 260 }
nuclear@1 261
nuclear@1 262 const char *fmtstr(int fmt)
nuclear@1 263 {
nuclear@1 264 switch(fmt) {
nuclear@1 265 case 0x86b0: return "GL_COMPRESSED_RGB_FXT1_3DFX";
nuclear@1 266 case 0x86b1: return "GL_COMPRESSED_RGBA_FXT1_3DFX";
nuclear@1 267 case 0x8dbb: return "GL_COMPRESSED_RED_RGTC1";
nuclear@1 268 case 0x8dbc: return "GL_COMPRESSED_SIGNED_RED_RGTC1";
nuclear@1 269 case 0x8dbd: return "GL_COMPRESSED_RG_RGTC2";
nuclear@1 270 case 0x8dbe: return "GL_COMPRESSED_SIGNED_RG_RGTC2";
nuclear@1 271 case 0x8e8c: return "GL_COMPRESSED_RGBA_BPTC_UNORM";
nuclear@1 272 case 0x8e8d: return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM";
nuclear@1 273 case 0x8e8e: return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT";
nuclear@1 274 case 0x8e8f: return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT";
nuclear@1 275 case 0x9274: return "GL_COMPRESSED_RGB8_ETC2";
nuclear@1 276 case 0x9275: return "GL_COMPRESSED_SRGB8_ETC2";
nuclear@1 277 case 0x9276: return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2";
nuclear@1 278 case 0x9277: return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2";
nuclear@1 279 case 0x9278: return "GL_COMPRESSED_RGBA8_ETC2_EAC";
nuclear@1 280 case 0x9279: return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC";
nuclear@1 281 case 0x9270: return "GL_COMPRESSED_R11_EAC";
nuclear@1 282 case 0x9271: return "GL_COMPRESSED_SIGNED_R11_EAC";
nuclear@1 283 case 0x9272: return "GL_COMPRESSED_RG11_EAC";
nuclear@1 284 case 0x9273: return "GL_COMPRESSED_SIGNED_RG11_EAC";
nuclear@1 285 case 0x83F0: return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT";
nuclear@1 286 case 0x83F1: return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT";
nuclear@1 287 case 0x83F2: return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT";
nuclear@1 288 case 0x83F3: return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT";
nuclear@1 289 case 0x8C48: return "GL_COMPRESSED_SRGB_EXT";
nuclear@1 290 case 0x8C49: return "GL_COMPRESSED_SRGB_ALPHA_EXT";
nuclear@1 291 case 0x8C4A: return "GL_COMPRESSED_SLUMINANCE_EXT";
nuclear@1 292 case 0x8C4B: return "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT";
nuclear@1 293 case 0x8C4C: return "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT";
nuclear@1 294 case 0x8C4D: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT";
nuclear@1 295 case 0x8C4E: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT";
nuclear@1 296 case 0x8C4F: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT";
nuclear@2 297 case 0x8B90: return "GL_PALETTE4_RGB8_OES";
nuclear@2 298 case 0x8B91: return "GL_PALETTE4_RGBA8_OES";
nuclear@2 299 case 0x8B92: return "GL_PALETTE4_R5_G6_B5_OES";
nuclear@2 300 case 0x8B93: return "GL_PALETTE4_RGBA4_OES";
nuclear@2 301 case 0x8B94: return "GL_PALETTE4_RGB5_A1_OES";
nuclear@2 302 case 0x8B95: return "GL_PALETTE8_RGB8_OES";
nuclear@2 303 case 0x8B96: return "GL_PALETTE8_RGBA8_OES";
nuclear@2 304 case 0x8B97: return "GL_PALETTE8_R5_G6_B5_OES";
nuclear@2 305 case 0x8B98: return "GL_PALETTE8_RGBA4_OES";
nuclear@2 306 case 0x8B99: return "GL_PALETTE8_RGB5_A1_OES";
nuclear@2 307 case 0x93B0: return "GL_COMPRESSED_RGBA_ASTC_4";
nuclear@2 308 case 0x93B1: return "GL_COMPRESSED_RGBA_ASTC_5";
nuclear@2 309 case 0x93B2: return "GL_COMPRESSED_RGBA_ASTC_5";
nuclear@2 310 case 0x93B3: return "GL_COMPRESSED_RGBA_ASTC_6";
nuclear@2 311 case 0x93B4: return "GL_COMPRESSED_RGBA_ASTC_6";
nuclear@2 312 case 0x93B5: return "GL_COMPRESSED_RGBA_ASTC_8";
nuclear@2 313 case 0x93B6: return "GL_COMPRESSED_RGBA_ASTC_8";
nuclear@2 314 case 0x93B7: return "GL_COMPRESSED_RGBA_ASTC_8";
nuclear@2 315 case 0x93B8: return "GL_COMPRESSED_RGBA_ASTC_10";
nuclear@2 316 case 0x93B9: return "GL_COMPRESSED_RGBA_ASTC_10";
nuclear@2 317 case 0x93BA: return "GL_COMPRESSED_RGBA_ASTC_10";
nuclear@2 318 case 0x93BB: return "GL_COMPRESSED_RGBA_ASTC_10";
nuclear@2 319 case 0x93BC: return "GL_COMPRESSED_RGBA_ASTC_12";
nuclear@2 320 case 0x93BD: return "GL_COMPRESSED_RGBA_ASTC_12";
nuclear@2 321 case 0x93D0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4";
nuclear@2 322 case 0x93D1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5";
nuclear@2 323 case 0x93D2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5";
nuclear@2 324 case 0x93D3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6";
nuclear@2 325 case 0x93D4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6";
nuclear@2 326 case 0x93D5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8";
nuclear@2 327 case 0x93D6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8";
nuclear@2 328 case 0x93D7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8";
nuclear@2 329 case 0x93D8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10";
nuclear@2 330 case 0x93D9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10";
nuclear@2 331 case 0x93DA: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10";
nuclear@2 332 case 0x93DB: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10";
nuclear@2 333 case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12";
nuclear@2 334 case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12";
nuclear@1 335 default:
nuclear@1 336 break;
nuclear@1 337 }
nuclear@1 338 return "unknown";
nuclear@1 339 }
nuclear@1 340
nuclear@1 341 void print_compressed_formats(void)
nuclear@1 342 {
nuclear@1 343 int i, num_fmt;
nuclear@1 344 int *fmtlist;
nuclear@1 345
nuclear@1 346 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_fmt);
nuclear@1 347 printf("%d generic compressed texture formats available:\n", num_fmt);
nuclear@1 348
nuclear@1 349 if(!(fmtlist = malloc(num_fmt * sizeof *fmtlist))) {
nuclear@1 350 fprintf(stderr, "failed to allocate texture formats enumeration buffer\n");
nuclear@1 351 return;
nuclear@1 352 }
nuclear@1 353 glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, fmtlist);
nuclear@1 354
nuclear@1 355 for(i=0; i<num_fmt; i++) {
nuclear@1 356 printf(" %05x: %s\n", fmtlist[i], fmtstr(fmtlist[i]));
nuclear@1 357 }
nuclear@1 358 free(fmtlist);
nuclear@1 359 }