next up previous
Next: explorer.cpp Up: SETI Visualizations: Development of Previous: Appendices

milky.cpp

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



Immanuel Buder 2003-06-03