/* mandlebrotgl.c */ #include #include #include #include #include static int width = 320; static int height = 360; /* 40 for text */ static double center_x = 0.0; static double center_y = 0.0; static double size = 4.0; static char message[] = "Click on new center. Type Q to stop, R to restart"; static int rgb[16][3] = { {000,000,000}, {255,000,000}, /* 0 black, 1 red */ {255,255,000}, {000,255,255}, /* 2 magenta, 3 yellow */ {000,255,000}, {000,000,255}, /* 4 green, 5 blue */ {100,180,160}, {255,255,255}, /* 6 violet, 7 white */ {240,180,000}, {255,000,255}, /* 8 orange, 9 cyan */ {100,240,200}, {100,200,240}, /* 10 aquamarine, 11 turquoise */ {255,200,200}, {100,255,255}, /* 12 pink, 13 goldenrod */ {170,170,170}, {240,240,100}}; /* 14 grey, 15 sienna */ /* function prototypes */ static void printstring(float x, float y, char *string); static void display(void); static void myReshape(int w, int h); static void myinit(void); static void keyboard(unsigned char key, int x, int y); static void special(int k, int x, int y); static void mouse(int button, int state, int x, int y); static void main_draw(void); static int pixelcolor(double c1, double c2); static void printstring(float x, float y, char *string) { int len, i; glRasterPos2f(x, y); len = (int) strlen(string); for (i = 0; i < len; i++) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, string[i]); } /* end printstring */ static void display(void) { glClear(GL_COLOR_BUFFER_BIT); main_draw(); glFlush(); } /* end display */ static void myReshape(int w, int h) { width = w; height = h; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0,(GLfloat)w, 0.0, (GLfloat)h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor (1.0, 1.0, 1.0, 0.0); } /* end myReshape */ void myinit(void) { int i; glClearColor (1.0, 1.0, 1.0, 0.0); } /* end myinit */ static void keyboard(unsigned char key, int x, int y) { switch (key) { case 'q': exit(0); case 'Q': exit(0); case 'r': case 'R': center_x = 0.0; center_y = 0.0; size = 4.0; break; } glutPostRedisplay(); } /* end keyboard */ static void special(int k, int x, int y) { switch(k) { case GLUT_KEY_LEFT: break; case GLUT_KEY_RIGHT: break; case GLUT_KEY_DOWN: break; case GLUT_KEY_UP: break; } glutPostRedisplay(); } /* end special */ static void mouse(int button, int state, int x, int y) { float center; double sizef; if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { printf("x=%d, y=%d \n", x, y); center = (float)width/2.0; center_x = center_x + (size/2.0) * (x - center)/center; center_y = center_y + (size/2.0) * (center - y + 40)/center; sizef = 4.0; size = size/sizef; printf("mouse center_x=%f, center_y=%f, size=%g \n", center_x, center_y, size); glutPostRedisplay(); } } /* end mouse */ static void main_draw(void) { int color; int p1, p2; double x_0, y_0, dx, dy, x, y; char d_num_str[30]; glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glColor3f(0.0, 0.0, 0.0); printstring( 5, height-35, message); sprintf(d_num_str, "size= %e ", size); printstring( 5, height-25, d_num_str); sprintf(d_num_str, "x= %e ", center_x); printstring( 5, height-15, d_num_str); sprintf(d_num_str, "y= %e ", center_y); printstring( width/2, height-15, d_num_str); dx = size/(double)width; dy = size/(double)(height-40); x_0 = center_x - (size/2.0); y_0 = center_y - (size/2.0); printf("draw_main center_x=%f, center_y=%f, size=%g \n", center_x, center_y, size); printf("main_draw x_0=%f, y_0=%f, dx=%f, dy=%f \n", x_0, y_0, dx, dy); glPointSize(1.0); glBegin(GL_POINTS); x = x_0; for (p1=0; p1<=width; p1++) { y = y_0; for (p2=0; p2<=height-40; p2++) { color = pixelcolor(x, y); glColor3f(rgb[color][0]/255.0, rgb[color][1]/255.0, rgb[color][2]/255.0); glVertex3f((GLfloat)p1, (GLfloat)p2, 0.0); y = y + dy; } x = x + dx; } glEnd(); } /* end of one main_draw */ /* generate pixel color */ static int pixelcolor(double c1, double c2) { double z1, z2, sqrz1, sqrz2; static int color; z1 = 0.0; z2 = 0.0; sqrz1 = 0.0; sqrz2 = 0.0; for(color=0; color<=255; color++) /* 255 should be 255 but much slower*/ { z2 = 2.0 * z1 * z2 + c2; z1 = sqrz1 - sqrz2 + c1; sqrz1 = z1 * z1; sqrz2 = z2 * z2; if ( (sqrz1 + sqrz2) > 4.0 ) return (color % 16); } return 0; } /* end pixelcolor */ int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB ); glutInitWindowSize(width, height); glutCreateWindow(argv[0]); glutReshapeFunc(myReshape); glutMouseFunc(mouse); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutDisplayFunc(display); myinit(); glutMainLoop(); return 0; } /* end main */ /* end mandelbrotgl.c */