// SETI Visualizations // by Immanuel Buder #include <stdlib.h> #include <iostream.h> #include <GL/glut.h> #include "tgaload.cpp" //routine for loading texture from targa #include <time.h> int mainwindow,controlwindow, Rbutton, fpbutton, nebutton; double R, fp, ne, fl, fi, fc, L; //Drake factors double P; //civilization density GLint height, width; //window size GLuint map; //texture, galaxy map GLint cheight, cwidth; //controol window size void display (); //main display function void outtext (double x, double y, double z, char *string, void *font); void drakeinit() { R= 10; //known with some accuracy fp = .2; //reasonable estimate ne = 1; // good... if we are average fl= 1; //optimistic fi = .9; //optimistic fc = .1; //blatant guess L = 1000; //low side of Dolphin range } void loadtextures () { //load texture glPixelStorei (GL_UNPACK_ALIGNMENT,1); glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); map = tgaLoadAndBind ("milky.tga",TGA_DEFAULT); //map identifies texture } void controldisplay () { glClear(GL_COLOR_BUFFER_BIT); //reset to background } void Rdisplay () { glClearColor (.6,.1,0,0); //background color glClear (GL_COLOR_BUFFER_BIT); //set background glLoadIdentity(); //put basic matrix into memory glOrtho (0,10,0,10,-1,1); //dimensions of view glColor3f (0,0,0); //write in black outtext (1,3,0,"R",GLUT_BITMAP_TIMES_ROMAN_24);//label glFlush(); //force drawing } void fldisplay () { glClearColor (.6,.1,0,0); glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity(); glOrtho (0,10,0,10,-1,1); glColor3f (0,0,0); outtext (1,3,0,"fl",GLUT_BITMAP_TIMES_ROMAN_24); glFlush(); } void fpdisplay () { glClearColor (.6,.1,0,0); glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity(); glOrtho (0,10,0,10,-1,1); glColor3f (0,0,0); outtext (1,3,0,"fp",GLUT_BITMAP_TIMES_ROMAN_24); glFlush(); } void Ldisplay () { glClearColor (.6,.1,0,0); glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity(); glOrtho (0,10,0,10,-1,1); glColor3f (0,0,0); outtext (1,3,0,"L",GLUT_BITMAP_TIMES_ROMAN_24); glFlush(); } void fidisplay () { glClearColor (.6,.1,0,0); glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity(); glOrtho (0,10,0,10,-1,1); glColor3f (0,0,0); outtext (1,3,0,"fi",GLUT_BITMAP_TIMES_ROMAN_24); glFlush(); } void fcdisplay () { glClearColor (.6,.1,0,0); glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity(); glOrtho (0,10,0,10,-1,1); glColor3f (0,0,0); outtext (1,3,0,"fc",GLUT_BITMAP_TIMES_ROMAN_24); glFlush(); } void Pdisplay () { glClearColor (.6,.1,0,0); glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity(); glOrtho (0,10,0,10,-1,1); glColor3f (0,0,0); outtext (1,3,0,"P",GLUT_BITMAP_TIMES_ROMAN_24); glFlush(); } void nedisplay () { glClearColor (.6,.1,0,0); glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity(); glOrtho (0,10,0,10,-1,1); glColor3f (0,0,0); outtext (1,3,0,"ne",GLUT_BITMAP_TIMES_ROMAN_24); glFlush(); } void nemouse (int button, int state, int x, int y) { if (state == GLUT_DOWN) { //if pressed cout<<"Enter a new value for ne, the number of earthlike planets per star."<<endl; cout<<"The old value is "<<ne<<endl; cout<<"This parameter is not well known; however, if the solar system is representative of other star systems, this number is between 1 and 5."<<endl; cin>>ne; glutPostWindowRedisplay(mainwindow); //redraw main window cout<<"ne changed to "<<ne<<endl; //inform user of change glFlush(); //force drawing } } void Rmouse (int button, int state, int x, int y) { if (state == GLUT_DOWN) { cout<<"Enter a new value for R, the number of stars formed per year."<<endl; cout<<"The old value is "<<R<<endl; cout<<"This parameter is believed to be between 1 and 20"<<endl; cin>>R; cout<<"R changed to "<<R<<endl; glutPostWindowRedisplay(mainwindow); glFlush(); } } void fcmouse (int button, int state, int x, int y) { if (state == GLUT_DOWN) { cout<<"Enter a new value for fc, the fraction of intelligent beings that communicate"<<endl; cout<<"The old value is "<<fc<<endl; cout<<"This parameter is largely unknown. Some guess it is between .1 and .2, since many intelligent beings do not develop technology (e.g. dolphins)."<<endl; cin>>fc; cout<<"fc changed to "<<fc<<endl; //inform user of change glutPostWindowRedisplay(mainwindow); glFlush(); } } void flmouse (int button, int state, int x, int y) { if (state == GLUT_DOWN) { cout<<"Enter a new value for fl, the fraction of earthlike planets on which life occurs"<<endl; cout<<"The old value is "<<fl<<endl; cout<<"This parameter is assumed to be close to 1, given how quickly life evolved on earth"<<endl; cin>>fl; cout<<"fl changed to "<<fl<<endl; //inform user of change glutPostWindowRedisplay(mainwindow); glFlush(); } } void fimouse (int button, int state, int x, int y) { if (state == GLUT_DOWN) { cout<<"Enter a new value for fi, the fraction of life-bearing planets which develop intelligence."<<endl; cout<<"The old value is "<<fi<<endl; cout<<"This parameter is believed to be close to 1, since intelligence has great survival value."<<endl; cin>>fi; cout<<"fi changed to "<<fi<<endl; //inform user of change glutPostWindowRedisplay(mainwindow); glFlush(); } } void Pmouse (int button, int state, int x, int y) { if (state == GLUT_DOWN) { cout<<"The current civilization density is "<<P<<endl; } } void Lmouse (int button, int state, int x, int y) { if (state == GLUT_DOWN) { cout<<"Enter a new value for L, the length of time (in years) a communicating civilization remains detectable."<<endl; cout<<"The old value is "<<L<<endl; cout<<"This parameter is guessed to be between 1,000 and 100,000,000"<<endl; cin>>L; cout<<"L changed to "<<L<<endl; //inform user of change glutPostWindowRedisplay(mainwindow); glFlush(); } } void fpmouse (int button, int state, int x, int y) { if (state == GLUT_DOWN) { cout<<"Enter a new value for fp, the fraction of stars with planets."<<endl; cout<<"The old value is "<<fp<<endl; cout<<"This parameter is believed to be between .2 and .5"<<endl; cin>>fp; cout<<"fp changed to "<<fp<<endl; //inform user of change glutPostWindowRedisplay(mainwindow); glFlush(); } } void initialize () { height = width = 500; //set size glutInitDisplayMode(GLUT_DEPTH|GLUT_SINGLE|GLUT_RGB); //single buffered mode glutInitWindowSize(width, height); mainwindow = glutCreateWindow("SETI Visualizations"); //create main window glutDisplayFunc(display); //function for main drawing glEnable(GL_RGB); //RGB mode glEnable (GL_TEXTURE_2D); //textures on glEnable(GL_DEPTH_TEST); // glDepthFunc(GL_LEQUAL); // more texture stuff glEnable(GL_BLEND); // glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // loadtextures(); //load texture from milky.tga glEnable(GL_RGB); glClearColor(.3,.3,.6,0); glMatrixMode(GL_PROJECTION); //create view glLoadIdentity(); glOrtho(-1,1,-1,1,-1,1); cwidth= 200; cheight = 200; //control window size glutInitWindowSize(cwidth, cheight); //control windoe controlwindow = glutCreateWindow("Controls"); glutDisplayFunc(controldisplay); //drawing function for controls glClearColor (1,1,1,1); glClear(GL_COLOR_BUFFER_BIT); //set background glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1,1,-1,1,-1,1); //create buttons Rbutton = glutCreateSubWindow(controlwindow, 10, 10, 22, 40); glutDisplayFunc (Rdisplay); //display function for buttons glutMouseFunc(Rmouse); //function for mouse click fpbutton = glutCreateSubWindow(controlwindow, 50, 10, 30, 40); glutDisplayFunc (fpdisplay); glutMouseFunc(fpmouse); nebutton = glutCreateSubWindow(controlwindow, 90, 10, 30, 40); glutDisplayFunc (nedisplay); glutMouseFunc(nemouse); glutCreateSubWindow(controlwindow, 130, 10, 20, 40); glutDisplayFunc(fldisplay); glutMouseFunc(flmouse); glutCreateSubWindow(controlwindow, 160, 10, 20, 40); glutDisplayFunc(fidisplay); glutMouseFunc(fimouse); glutCreateSubWindow(controlwindow, 10, 60, 30, 40); glutDisplayFunc(fcdisplay); glutMouseFunc(fcmouse); glutCreateSubWindow(controlwindow, 50, 60, 30, 40); glutDisplayFunc(Ldisplay); glutMouseFunc(Lmouse); glutCreateSubWindow(controlwindow, 90, 60, 30, 40); glutDisplayFunc(Pdisplay); glutMouseFunc(Pmouse); } void outtext (double x, double y, double z, char *string, void *font) { glRasterPos3f(x,y,z); //locate position for output int len = strlen (string); //find length of output for (int i = 0; i < len; i++) { glutBitmapCharacter(font,string[i]); //output by chars } } void display () { glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); //clear glBindTexture(GL_TEXTURE_2D, map); //use texture glColor3f (1.0,1.0,1.0); glBegin(GL_QUADS); //square, background glTexCoord2f (0,0); //point on texture glVertex3f (-1,-1,.1); //point on screen glTexCoord2f (0,1); glVertex3f (-1,1,.1); glTexCoord2f (1,1); glVertex3f (1,1,.1); glTexCoord2f (1,0); glVertex3f (1,-1,.1); glEnd(); //done with quads glColor3f(1.0,1.,1.0); //set draw color glBegin(GL_POINTS); //begin drawing points glColor3f(1.0,0,0); //set draw color double x,y, xstep, ystep, points; xstep = ystep = .005; //dist between points points = 4/ (xstep * ystep); //number of possible points on screen P = R*fp*ne*fl*fi*fc*L/points; //current point density if (P >= 1) cout<<"Warning: maximum saturation reached"<<endl; for (x = -1; x <1; x+= xstep) //move across screen for (y = -1; y < 1; y += ystep) if (P > (double(rand())/double(RAND_MAX))) glVertex3f(x,y,0.2); //draw point glEnd(); //done with points glFlush(); //force drawing } int main (int argc, char ** argv) { srand(unsigned(time(NULL))); //seed random numbers drakeinit(); //initialize Drake factors glutInit(&argc, argv); //initialize graphics initialize(); //more graphics initialization glutMainLoop(); //hand control over to OpenGL return 0; }