# HG changeset patch # User John Tsiombikas # Date 1515478512 -7200 # Node ID f941fd7128c52a13c4c02a820dd0abdb1dd08bb0 initial commit diff -r 000000000000 -r f941fd7128c5 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Tue Jan 09 08:15:12 2018 +0200 @@ -0,0 +1,12 @@ +obj = main.o +bin = test + +CFLAGS = -pedantic -Wall -g +LDFLAGS = -lGL -lglut + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 000000000000 -r f941fd7128c5 main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.c Tue Jan 09 08:15:12 2018 +0200 @@ -0,0 +1,231 @@ +#include +#include +#include +#include +#include +#include + +#undef USE_SRGB + +#ifdef USE_SRGB +#define COMP_FMT GL_COMPRESSED_SRGB8_ETC2 +#else +#define COMP_FMT GL_COMPRESSED_RGB8_ETC2 +#endif + +int init(void); +int texcomp(unsigned char *compix, unsigned int tofmt, unsigned char *pixels, + int xsz, int ysz, unsigned int fromfmt, unsigned int fromtype); +void disp(void); +void reshape(int x, int y); +void keyb(unsigned char key, int x, int y); +void gen_image(unsigned char *pixels, int xsz, int ysz); + +unsigned int tex, comp_tex; +const char *texfile; + +int main(int argc, char **argv) +{ + unsigned int glut_flags = GLUT_RGB | GLUT_DOUBLE; +#ifdef USE_SRGB + glut_flags |= GLUT_SRGB; +#endif + + texfile = argv[1]; + + glutInit(&argc, argv); + glutInitWindowSize(800, 600); + glutInitDisplayMode(glut_flags); + glutCreateWindow("test"); + + glutDisplayFunc(disp); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + + if(init() == -1) { + return 1; + } + + glutMainLoop(); + return 0; +} + +int init(void) +{ + unsigned char *pixels, *buf; + int xsz = 512; + int ysz = 512; + int is_comp = 0; + int comp_size = 0; + int start, tmp; + FILE *fp; + + if(texfile) { + if(!(fp = fopen(texfile, "rb"))) { + fprintf(stderr, "failed to open compressed texture file: %s: %s\n", texfile, strerror(errno)); + return -1; + } + + if(fread(&xsz, sizeof xsz, 1, fp) < 1 || fread(&ysz, sizeof ysz, 1, fp) < 1) { + fprintf(stderr, "failed to read compressed texture file header: %s: %s\n", texfile, strerror(errno)); + fclose(fp); + return -1; + } + start = ftell(fp); + fseek(fp, 0, SEEK_END); + comp_size = ftell(fp) - start; + fseek(fp, start, SEEK_SET); + + if(!(pixels = malloc(comp_size))) { + abort(); + } + if(fread(pixels, 1, comp_size, fp) < comp_size) { + fprintf(stderr, "failed to read compressed texture file: %s: %s\n", texfile, strerror(errno)); + fclose(fp); + free(pixels); + return -1; + } + fclose(fp); + + printf("loaded compressed texture file: %s (%dx%d)\n", texfile, xsz, ysz); + + } else { + if(!(pixels = malloc(xsz * ysz * 3))) { + abort(); + } + gen_image(pixels, xsz, ysz); + + printf("compressing texture\n"); + if((comp_size = texcomp(pixels, COMP_FMT, pixels, xsz, ysz, GL_RGB, GL_UNSIGNED_BYTE)) == -1) { + return -1; + } + printf("compressed texture is %d bytes (uncompressed was: %d)\n", comp_size, xsz * ysz * 3); + + /* dump compressed texture */ + if(!(fp = fopen("compressed_texture", "wb"))) { + fprintf(stderr, "failed to open compressed texture dump file: %s\n", strerror(errno)); + } else { + if(fwrite(&xsz, sizeof xsz, 1, fp) < 1 || + fwrite(&ysz, sizeof ysz, 1, fp) < 1 || + fwrite(pixels, 1, comp_size, fp) < comp_size) { + fprintf(stderr, "failed to dump compressed texture: %s\n", strerror(errno)); + } + fclose(fp); + } + } + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, COMP_FMT, xsz, ysz, 0, comp_size, pixels); + if(glGetError()) { + fprintf(stderr, "failed to upload compressed texture\n"); + return -1; + } + + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_comp); + if(!is_comp) { + fprintf(stderr, "texture is not compressed\n"); + return -1; + } + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &tmp); + if(tmp != comp_size) { + fprintf(stderr, "internal compressed size differs (expected: %d, got: %d)!\n", comp_size, tmp); + return -1; + } + + if(!(buf = malloc(comp_size))) { + fprintf(stderr, "failed to allocate comparison image buffer (%d bytes)\n", comp_size); + return -1; + } + glGetCompressedTexImage(GL_TEXTURE_2D, 0, buf); + + if(memcmp(pixels, buf, comp_size) != 0) { + fprintf(stderr, "submitted and retrieved pixel data differ!\n"); + return -1; + } + printf("submitted and retrieved sizes match (%d bytes)\n", comp_size); + free(buf); + free(pixels); + +#ifdef USE_SRGB + glEnable(GL_FRAMEBUFFER_SRGB); +#endif + + glEnable(GL_TEXTURE_2D); + return 0; +} + +int texcomp(unsigned char *compix, unsigned int tofmt, unsigned char *pixels, + int xsz, int ysz, unsigned int fromfmt, unsigned int fromtype) +{ + unsigned int tex; + int is_comp = 0; + int comp_size = 0; + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, tofmt, xsz, ysz, 0, fromfmt, fromtype, pixels); + if(glGetError()) { + fprintf(stderr, "failed to compress texture\n"); + return -1; + } + + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_comp); + if(!is_comp) { + fprintf(stderr, "texture is not compressed\n"); + return -1; + } + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &comp_size); + + glGetCompressedTexImage(GL_TEXTURE_2D, 0, compix); + return comp_size; +} + +void disp(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex2f(-1, -1); + glTexCoord2f(1, 1); glVertex2f(1, -1); + glTexCoord2f(1, 0); glVertex2f(1, 1); + glTexCoord2f(0, 0); glVertex2f(-1, 1); + glEnd(); + + glutSwapBuffers(); + assert(glGetError() == GL_NO_ERROR); +} + +void reshape(int x, int y) +{ + float aspect = (float)x / (float)y; + glViewport(0, 0, x, y); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glScalef(1.0 / aspect, 1, 1); +} + +void keyb(unsigned char key, int x, int y) +{ + if(key == 27) { + exit(0); + } +} + +void gen_image(unsigned char *pixels, int xsz, int ysz) +{ + int i, j; + + for(i=0; i