test_texcomp

view main.c @ 0:f941fd7128c5

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 09 Jan 2018 08:15:12 +0200
parents
children ed40258af7ad
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <assert.h>
6 #include <GL/freeglut.h>
8 #undef USE_SRGB
10 #ifdef USE_SRGB
11 #define COMP_FMT GL_COMPRESSED_SRGB8_ETC2
12 #else
13 #define COMP_FMT GL_COMPRESSED_RGB8_ETC2
14 #endif
16 int init(void);
17 int texcomp(unsigned char *compix, unsigned int tofmt, unsigned char *pixels,
18 int xsz, int ysz, unsigned int fromfmt, unsigned int fromtype);
19 void disp(void);
20 void reshape(int x, int y);
21 void keyb(unsigned char key, int x, int y);
22 void gen_image(unsigned char *pixels, int xsz, int ysz);
24 unsigned int tex, comp_tex;
25 const char *texfile;
27 int main(int argc, char **argv)
28 {
29 unsigned int glut_flags = GLUT_RGB | GLUT_DOUBLE;
30 #ifdef USE_SRGB
31 glut_flags |= GLUT_SRGB;
32 #endif
34 texfile = argv[1];
36 glutInit(&argc, argv);
37 glutInitWindowSize(800, 600);
38 glutInitDisplayMode(glut_flags);
39 glutCreateWindow("test");
41 glutDisplayFunc(disp);
42 glutReshapeFunc(reshape);
43 glutKeyboardFunc(keyb);
45 if(init() == -1) {
46 return 1;
47 }
49 glutMainLoop();
50 return 0;
51 }
53 int init(void)
54 {
55 unsigned char *pixels, *buf;
56 int xsz = 512;
57 int ysz = 512;
58 int is_comp = 0;
59 int comp_size = 0;
60 int start, tmp;
61 FILE *fp;
63 if(texfile) {
64 if(!(fp = fopen(texfile, "rb"))) {
65 fprintf(stderr, "failed to open compressed texture file: %s: %s\n", texfile, strerror(errno));
66 return -1;
67 }
69 if(fread(&xsz, sizeof xsz, 1, fp) < 1 || fread(&ysz, sizeof ysz, 1, fp) < 1) {
70 fprintf(stderr, "failed to read compressed texture file header: %s: %s\n", texfile, strerror(errno));
71 fclose(fp);
72 return -1;
73 }
74 start = ftell(fp);
75 fseek(fp, 0, SEEK_END);
76 comp_size = ftell(fp) - start;
77 fseek(fp, start, SEEK_SET);
79 if(!(pixels = malloc(comp_size))) {
80 abort();
81 }
82 if(fread(pixels, 1, comp_size, fp) < comp_size) {
83 fprintf(stderr, "failed to read compressed texture file: %s: %s\n", texfile, strerror(errno));
84 fclose(fp);
85 free(pixels);
86 return -1;
87 }
88 fclose(fp);
90 printf("loaded compressed texture file: %s (%dx%d)\n", texfile, xsz, ysz);
92 } else {
93 if(!(pixels = malloc(xsz * ysz * 3))) {
94 abort();
95 }
96 gen_image(pixels, xsz, ysz);
98 printf("compressing texture\n");
99 if((comp_size = texcomp(pixels, COMP_FMT, pixels, xsz, ysz, GL_RGB, GL_UNSIGNED_BYTE)) == -1) {
100 return -1;
101 }
102 printf("compressed texture is %d bytes (uncompressed was: %d)\n", comp_size, xsz * ysz * 3);
104 /* dump compressed texture */
105 if(!(fp = fopen("compressed_texture", "wb"))) {
106 fprintf(stderr, "failed to open compressed texture dump file: %s\n", strerror(errno));
107 } else {
108 if(fwrite(&xsz, sizeof xsz, 1, fp) < 1 ||
109 fwrite(&ysz, sizeof ysz, 1, fp) < 1 ||
110 fwrite(pixels, 1, comp_size, fp) < comp_size) {
111 fprintf(stderr, "failed to dump compressed texture: %s\n", strerror(errno));
112 }
113 fclose(fp);
114 }
115 }
117 glGenTextures(1, &tex);
118 glBindTexture(GL_TEXTURE_2D, tex);
119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
121 glCompressedTexImage2D(GL_TEXTURE_2D, 0, COMP_FMT, xsz, ysz, 0, comp_size, pixels);
122 if(glGetError()) {
123 fprintf(stderr, "failed to upload compressed texture\n");
124 return -1;
125 }
127 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_comp);
128 if(!is_comp) {
129 fprintf(stderr, "texture is not compressed\n");
130 return -1;
131 }
132 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &tmp);
133 if(tmp != comp_size) {
134 fprintf(stderr, "internal compressed size differs (expected: %d, got: %d)!\n", comp_size, tmp);
135 return -1;
136 }
138 if(!(buf = malloc(comp_size))) {
139 fprintf(stderr, "failed to allocate comparison image buffer (%d bytes)\n", comp_size);
140 return -1;
141 }
142 glGetCompressedTexImage(GL_TEXTURE_2D, 0, buf);
144 if(memcmp(pixels, buf, comp_size) != 0) {
145 fprintf(stderr, "submitted and retrieved pixel data differ!\n");
146 return -1;
147 }
148 printf("submitted and retrieved sizes match (%d bytes)\n", comp_size);
149 free(buf);
150 free(pixels);
152 #ifdef USE_SRGB
153 glEnable(GL_FRAMEBUFFER_SRGB);
154 #endif
156 glEnable(GL_TEXTURE_2D);
157 return 0;
158 }
160 int texcomp(unsigned char *compix, unsigned int tofmt, unsigned char *pixels,
161 int xsz, int ysz, unsigned int fromfmt, unsigned int fromtype)
162 {
163 unsigned int tex;
164 int is_comp = 0;
165 int comp_size = 0;
167 glGenTextures(1, &tex);
168 glBindTexture(GL_TEXTURE_2D, tex);
169 glTexImage2D(GL_TEXTURE_2D, 0, tofmt, xsz, ysz, 0, fromfmt, fromtype, pixels);
170 if(glGetError()) {
171 fprintf(stderr, "failed to compress texture\n");
172 return -1;
173 }
175 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_comp);
176 if(!is_comp) {
177 fprintf(stderr, "texture is not compressed\n");
178 return -1;
179 }
180 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &comp_size);
182 glGetCompressedTexImage(GL_TEXTURE_2D, 0, compix);
183 return comp_size;
184 }
186 void disp(void)
187 {
188 glClear(GL_COLOR_BUFFER_BIT);
190 glBegin(GL_QUADS);
191 glTexCoord2f(0, 1); glVertex2f(-1, -1);
192 glTexCoord2f(1, 1); glVertex2f(1, -1);
193 glTexCoord2f(1, 0); glVertex2f(1, 1);
194 glTexCoord2f(0, 0); glVertex2f(-1, 1);
195 glEnd();
197 glutSwapBuffers();
198 assert(glGetError() == GL_NO_ERROR);
199 }
201 void reshape(int x, int y)
202 {
203 float aspect = (float)x / (float)y;
204 glViewport(0, 0, x, y);
206 glMatrixMode(GL_PROJECTION);
207 glLoadIdentity();
208 glScalef(1.0 / aspect, 1, 1);
209 }
211 void keyb(unsigned char key, int x, int y)
212 {
213 if(key == 27) {
214 exit(0);
215 }
216 }
218 void gen_image(unsigned char *pixels, int xsz, int ysz)
219 {
220 int i, j;
222 for(i=0; i<ysz; i++) {
223 for(j=0; j<xsz; j++) {
224 int xor = i ^ j;
226 *pixels++ = xor & 0xff;
227 *pixels++ = (xor << 1) & 0xff;
228 *pixels++ = (xor << 2) & 0xff;
229 }
230 }
231 }