/* genmipmap.c - by David Blythe, SGI */ /* Example of how to generate texture mipmap levels with the accumulation buffer. */ /* Usage example: genmipmap [file.rgb] */ #include #include #include #include #include "texture.h" static int w = 512, h = 512; static int pause; void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, w, 0, h, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void init_textures(char *filename) { unsigned *buf; int width, height, components; if (filename) { buf = read_texture(filename, &width, &height, &components); if (buf == NULL) { fprintf(stderr, "Error: Can't load image file \"%s\".\n", filename); exit(1); } else { printf("%d x %d texture loaded\n", width, height); } } else { int i, j; GLubyte *p; components = 4; width = height = 512; buf = (unsigned *) malloc(width * height * sizeof(unsigned)); p = (GLubyte *) buf; for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { if (i & 1) p[4 * (i + j * width) + 0] = 0xff; else p[4 * (i + j * width) + 1] = 0xff; if (j & 1) p[4 * (i + j * width) + 2] = 0xff; } } } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); free(buf); } void init(char *filename) { glEnable(GL_TEXTURE_2D); init_textures(filename); } void draw_rect(int w, int h) { glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(0, 0); glTexCoord2f(1, 0); glVertex2f(w, 0); glTexCoord2f(1, 1); glVertex2f(w, h); glTexCoord2f(0, 1); glVertex2f(0, h); glEnd(); } void stop(void) { if (pause) { printf("? "); fflush(stdout); getchar(); } } void acfilter(int width, int height) { glClear(GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); glMatrixMode(GL_TEXTURE); if (pause) { draw_rect(width, height); stop(); glClear(GL_COLOR_BUFFER_BIT); } draw_rect(width / 2, height / 2); stop(); glAccum(GL_ACCUM, 0.25); glTranslatef(1.0 / width, 0, 0); draw_rect(width / 2, height / 2); stop(); glAccum(GL_ACCUM, 0.25); glLoadIdentity(); glTranslatef(0, 1.0 / height, 0); draw_rect(width / 2, height / 2); stop(); glAccum(GL_ACCUM, 0.25); glLoadIdentity(); glTranslatef(1.0 / width, 1.0 / height, 0); draw_rect(width / 2, height / 2); stop(); glAccum(GL_ACCUM, 0.25); glAccum(GL_RETURN, 1.0); glMatrixMode(GL_MODELVIEW); } void display(void) { glClear(GL_COLOR_BUFFER_BIT); draw_rect(w, h); acfilter(w, h); glFlush(); } void help(void) { printf("'h' - help\n"); printf("'s' - toggle single step mode\n"); } /* ARGSUSED1 */ void key(unsigned char key, int x, int y) { switch (key) { case 'h': help(); break; case 's': pause ^= 1; break; case '\033': exit(0); break; default: glutPostRedisplay(); } } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitWindowSize(w, h); glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM); (void) glutCreateWindow("genmipmap"); if (argc > 1) init(argv[1]); else init(0); glutDisplayFunc(display); glutKeyboardFunc(key); glutReshapeFunc(reshape); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }