|
// PVM Mandelbrot Set Program // Tom Dixon - Supercomp Period 3 #include</usr/pvm3/include/pvm3.h> #include<GL/glut.h> #include<iostream.h> #include<malloc.h> #include<assert.h> int xsize = 500, ysize = 500, ok=0; double x1=-2.5, x2=1.5, y1=-2, y2=2, zx, zy, ***screen; // PVM variables const int TASKS = 10; int tids[TASKS]; struct pvmhostinfo *hostp[TASKS]; #include "mtga.h" void init() { glClearColor(0,0,0,0); glShadeModel(GL_FLAT); if (pvm_spawn("mjslave", (char**)0, 0, "", TASKS, tids) < TASKS) { cout << "Error spawning tasks - halt everything" << endl; exit(1); } } void display() { if (ok) { cout << "Displaying" << endl; glBegin(GL_POINTS); for(int x=0; x<xsize; x++) for(int y=0; y<ysize; y++) { glColor3f(screen[x][y][0], screen[x][y][1], screen[x][y][2]); glVertex3f(x+0.5, y+0.5, 0); } glEnd(); } else { free(screen); screen = (double***)calloc(xsize, sizeof(double**)); for (int i=0; i<xsize; i++) { screen[i] = (double**)calloc(ysize, sizeof(double*)); for(int j=0; j<ysize; j++) screen[i][j]= (double*)calloc(3, sizeof(double)); } assert(screen); glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glBegin(GL_POINTS); double a, b, ta, x ,y; int it, max=-1, min=10000, maxit=int(1/(x2-x1)+1/(y2-y1)+20); for(int i=0; i<xsize; i++) for(int j=0; j<ysize; j++) { x=x1+(x2-x1)*i/xsize; y=y2-(y2-y1)*j/ysize; it=0; a=x; b=y; while (it<maxit && a*a+b*b<4) { ta=a*a-b*b+x; b=2*a*b+y; a=ta; it++; } if (it>max) max=it; if (it<min) min=it; } maxit=max; for (int t=0; t<TASKS; t++) { pvm_initsend(PvmDataDefault); pvm_pkint(&t, 1, 1); pvm_pkdouble(&y1, 1, 1); pvm_pkdouble(&y2, 1, 1); pvm_pkint(&ysize, 1, 1); pvm_pkint(&max, 1, 1); pvm_pkint(&min, 1, 1); pvm_send(tids[t], 69); } int col, who, rcol; for(col=0; col<TASKS; col++) { x=x1+(x2-x1)*col/xsize; pvm_initsend(PvmDataDefault); pvm_pkint(&col, 1, 1); pvm_pkdouble(&x, 1, 1); pvm_send(tids[col], 666); } while (col<xsize) { int rcol; pvm_recv(-1, 254); pvm_upkint(&who, 1, 1); pvm_upkint(&rcol, 1, 1); for(int i=0; i<ysize; i++) pvm_upkdouble(screen[rcol][i], 3, 1); x=x1+(x2-x1)*col/xsize; pvm_initsend(PvmDataDefault); pvm_pkint(&col, 1, 1); pvm_pkdouble(&x, 1, 1); pvm_send(tids[who], 666); col++; } ok=1; glutPostRedisplay(); cout << "done" << endl; } } void reshape(int w, int h) { xsize=w; ysize=h; glViewport(0, 0, GLsizei(w), GLsizei(h)); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, xsize, 0, ysize, -1, 1); glMatrixMode(GL_MODELVIEW); ok=0; } void showit(int x, int y) { double a=x1+(x2-x1)*x/xsize, ia=a, b=y2-(y2-y1)*y/ysize, ib=b, ta; int it=0; glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_STRIP); while (it<100 && a*a+b*b<4) { glVertex3f(a, b, 0); ta=a*a-b*b+ia; b=2*a*b+ib; a=ta; it++; } glVertex3f(a, b, 0); glEnd(); ok=0; } void zoom(int button, int state, int x, int y) { if (button==GLUT_MIDDLE_BUTTON) showit(x, y); else if (button==GLUT_RIGHT_BUTTON) { x1=-2.5; x2=2; y1=-2; y2=2; reshape(xsize, ysize); glutPostRedisplay(); } else if (button==GLUT_LEFT_BUTTON) { if (state==GLUT_DOWN) { zx=x1+(x2-x1)*x/xsize; zy=y2-(y2-y1)*y/ysize; } else { x2=x1+(x2-x1)*x/xsize; y1=y2-(y2-y1)*y/ysize; x1=zx; y2=zy; reshape(xsize, ysize); glutPostRedisplay(); } } } void keyboard(unsigned char ch, int x, int y) { if (ch=='t' || ch=='T') writetga(); } void main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(xsize, ysize); glutInitWindowPosition(100, 100); glutCreateWindow("PVM Mandelbrot-o-Rama"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(zoom); glutKeyboardFunc(keyboard); glutMainLoop(); } |