/*** INCLUDES ***/ #include #include #include #include #include #include #include #include "keys.h" /*** DEFINES ***/ #define fsck X( #define LPOINTS 1 #define LLINES 2 #define LLINESTRIPS 3 /*** GLOBALS ***/ int screenx=640; int screeny=480; int wid; /* window id */ float xrot=-90.0,yrot=0,zrot=-45.0; float ztrans=-150.0, xtrans=0.0,ytrans=-30.0; float a=3.2f,b=29.0f,c=2.5f; int maxiter=2500; int style=3; /*** FUNCTIONS ***/ float myabs(float x) { if (x>0) return x; else return -1*x; } void myquit() { glutDestroyWindow(wid); exit(0); } void glinit (int width, int height) { glShadeModel(GL_SMOOTH); glClearColor(0.0f,0.0f,0.0f,0.5f); glClearDepth(1.0f); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); glLoadIdentity(); gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); } GLvoid resizef(GLsizei Width, GLsizei Height) { //GLvoid resizef(int Width, int Height) { if (Height==0) Height=1; glViewport(0,0,Width,Height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,10000.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void renderf() { int i,j,k; float xo,yo,zo; float x,y,z,t; float col; glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* goto 0,0,0 */ glTranslatef(xtrans,ytrans, ztrans); glRotatef(xrot, 1,0,0); //x glRotatef(yrot, 0,1,0); //y glRotatef(zrot, 0,0,1); //z /* grid */ glColor3f(.1,.1,.1); glBegin(GL_LINES); for (i=-200;i<=200;i+=20){ glVertex3f((float)i, 200.0, 0.0); glVertex3f((float)i, -200.0, 0.0); glVertex3f(200.0, (float)i, 0.0); glVertex3f(-200.0,(float)i, 0.0); } glEnd(); glColor3f(1,1,1); if (style==LPOINTS) { glPointSize(2.0); glBegin(GL_POINTS); } else if (style==LLINES) glBegin(GL_LINES); else glBegin(GL_LINE_STRIP); xo=0.1f; yo=0.0f; zo=0.0f; t=0.01f; for (i=0;i<=maxiter;i++) { x= a*t* (yo-xo) + xo; y= t* (xo*b - xo*zo - yo) +yo; z= t* (xo*yo - c*zo) + zo; //col=(float)i/(float)maxiter; //glColor3f(col/3.0+.25,col+.25,col+.25); //glColor3f( (1-col)*.5, (1-col)*.75, 1-col); glColor3f(.3,.3,.3); glVertex3f(x,y,z); xo=x; yo=y; zo=z; } glEnd(); //myquit(); glutSwapBuffers(); usleep(0); } void keyf(unsigned char key, int x, int y) { usleep(100); printf("x: %d, y: %d\n", x,y); switch (key) { // quit case KEY_ESC: glutDestroyWindow(wid); exit(0); break; // screenshot case KEY_M: case KEY_m: writetiff("screen.tif", "libtiff", 0, 0, screenx, screeny, 1); printf("screen.tif saved\n"); break; //uio jkl case KEY_u: case KEY_U: a+=.1f; printf("a=%f, b=%f, c=%f\n",a,b,c); break; case KEY_j: case KEY_J: a-=.1f; printf("a=%f, b=%f, c=%f\n",a,b,c); break; //uio jkl case KEY_i: case KEY_I: b+=.1f; printf("a=%f, b=%f, c=%f\n",a,b,c); break; case KEY_k: case KEY_K: b-=.1f; printf("a=%f, b=%f, c=%f\n",a,b,c); break; //uio jkl case KEY_o: case KEY_O: c+=.1f; printf("a=%f, b=%f, c=%f\n",a,b,c); break; case KEY_l: case KEY_L: c-=.1f; printf("a=%f, b=%f, c=%f\n",a,b,c); break; //control case KEY_W: case KEY_w: ytrans-=2; break; case KEY_s: case KEY_S: ytrans+=2; break; case KEY_A: case KEY_a: xtrans+=2; break; case KEY_D: case KEY_d: xtrans-=2; break; case KEY_Q: case KEY_q: ztrans-=2; break; case KEY_E: case KEY_e: ztrans+=2; break; // increace iters case KEY_LB: maxiter-=25; printf("Max iterations: %d\n", maxiter); break; case KEY_RB: maxiter+=25; printf("Max iterations: %d\n", maxiter); break; } } void specialkeyf(int key, int x, int y) { usleep(100); switch (key) { case GLUT_KEY_LEFT: zrot+=5.0; printf("Zrot: %f\n",zrot); break; case GLUT_KEY_RIGHT: zrot-=5.0; printf("Zrot: %f\n",zrot); break; case GLUT_KEY_UP: xrot+=5.0;printf("Xrot: %f\n",xrot); break; case GLUT_KEY_DOWN: xrot-=5.0; printf("Xrot: %f\n",xrot); break; } } void menu(int value) { switch (value) { case 1: style=LPOINTS; break; case 2: style=LLINES; break; case 3: style=LLINESTRIPS; break; } } int main(int argc, char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode( GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH ); glutInitWindowSize(640,480); glutInitWindowPosition(0,0); wid = glutCreateWindow("fractal eyes"); glutDisplayFunc(&renderf); //glutFullScreen(); glutIdleFunc(&renderf); glutKeyboardFunc(keyf); glutSpecialFunc(&specialkeyf); glutReshapeFunc(&resizef); glutCreateMenu(menu); glutAddMenuEntry("Show points", 1); glutAddMenuEntry("Show disconnected lines", 2); glutAddMenuEntry("Show continuous lines", 3); glutAttachMenu(GLUT_RIGHT_BUTTON); resizef(640,480); glinit(640,480); glutMainLoop(); return 1; } int writetiff(char *filename, char *description, int x, int y, int width, int height, int compression) { TIFF *file; GLubyte *image, *p; int i; file = TIFFOpen(filename, "w"); if (file == NULL) { return 1; } image = (GLubyte *) malloc(width * height * sizeof(GLubyte) * 3); /* OpenGL's default 4 byte pack alignment would leave extra bytes at the end of each image row so that each full row contained a number of bytes divisible by 4. Ie, an RGB row with 3 pixels and 8-bit componets would be laid out like "RGBRGBRGBxxx" where the last three "xxx" bytes exist just to pad the row out to 12 bytes (12 is divisible by 4). To make sure the rows are packed as tight as possible (no row padding), set the pack alignment to 1. */ glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image); TIFFSetField(file, TIFFTAG_IMAGEWIDTH, (uint32) width); TIFFSetField(file, TIFFTAG_IMAGELENGTH, (uint32) height); TIFFSetField(file, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(file, TIFFTAG_COMPRESSION, compression); TIFFSetField(file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); TIFFSetField(file, TIFFTAG_SAMPLESPERPIXEL, 3); TIFFSetField(file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(file, TIFFTAG_ROWSPERSTRIP, 1); TIFFSetField(file, TIFFTAG_IMAGEDESCRIPTION, description); p = image; for (i = height - 1; i >= 0; i--) { if (TIFFWriteScanline(file, p, i, 0) < 0) { free(image); TIFFClose(file); return 1; } p += width * sizeof(GLubyte) * 3; } TIFFClose(file); return 0; }