|

// 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();
}
|