/* * darwinView * Written by Marissa Weichman June-July 2007 * Contact: mweichman@gmail.com * * See the darwinView Guide for instructions on using this program. * * The program begins running at main(), at the bottom of this file. The function * readjet() reads in the rgb for the color scale, while readnames() fills the array * fns[][][] with the appropriate filenames to read data from. The functions that * do the reading in are readxy(), readxz() and readyz() depending upon which plane * is being viewed (xy, xz and yz, respectively). The functions global() and local() * calculate the global and local maximum and minimum of the data sets. The key() * and specialkey() functions handle keyboard input from the user. Everytime a key * push changes any information, the display() function is called, which redisplays * the plots with the new values. Finally, TimerFunction() is called when the * autoplay feature is set, and an arrow key is pushed. TimerFunction() calls itself * recursively, and redisplays every 10th of a second as it scrolls through time, * depth levels, etc. */ #include #include #include #include #include #define WINDOW "image" #define UP 101 #define DOWN 103 #define RIGHT 102 #define LEFT 100 #define MAX 100 #define SCALE .06 int NX, NY, NZ; void do_byteswap_f32( float arr[], int nel ), global(), local( int, int, int ); void TimerFunction( int ), stroke( char[], int, int ); void readxy( float[], char[], int), readxz( float[], char[] ), readyz( float[], char[] ); void readnames( char[] ), readjet(), readdepths( char[] ); float data[MAX][MAX*MAX], mxval, mnval, jet[64][3], globalmx=0, globalmn=100; int glo=0, usr=0, anim=0, endian=1, logscale=0, xz=0, yz=0, nonegs=1, scaledepth=0; int win[MAX], depths[MAX], ilev=1, howmany, sets, count=0, xmax, ymax, yoffset=0, xoffset=0; int totaldepth=0, scalecount=0; char initfns[MAX][MAX], fns[MAX][MAX][MAX]; void menu( int value ){ // called when menu is opened on right click switch( value ){ case 1: usr=glo=0; // unset glo & usr, sets local max/min break; case 2: glo=1; // enables global max/min usr=0; // unsets usr mxval=globalmx; // sets max to globalmx mnval=globalmn; // sets min to globalmn break; case 3: usr=1; // switch to user-set max/min glo=0; // unset glo printf( "Max = " ); scanf( "%f", &mxval ); // prompt user for new max printf( "Min = " ); scanf( "%f", &mnval ); // prompt user for new min break; case 4: logscale=( logscale+1 )%2; // toggle log scale break; case 5: nonegs=( nonegs+1 )%2; // toggle allowance of negatives break; case 6: endian=( endian+1 )%2; // toggle big/little endian break; } glutPostRedisplay(); // redisplay with new values } void display(){ // called on glutPostRedisplay int i, h, ioff, q; float r, g, b, k, y, j, tmp; double num, logmx, logmn; char str[MAX]; for( q=0; qlogmx ) num=63; // set data more than max to max else num=63*( num-logmn )/( logmx-logmn ); // scale all others } } else{ // if not logscale if( data[q][ioff]mxval ) num=63; // set data more than max to max else num=63*( data[q][ioff]-mnval )/( mxval-mnval ); // scale all others } } r=jet[(int)num][0]; // set red value g=jet[(int)num][1]; // set green value b=jet[(int)num][2]; // set blue value } glColor3f( r, g, b ); // put r, g, b into effect if( scaledepth && xz || scaledepth && yz ) // if scaledepth is set glRectf( i, j, i+1, j+(depths[h]*tmp) ); // draw box appropriate to width of level else // otherwise glRectf( i, j, i+1, j+1 ); // draw a square ioff++; } // leave x loop if( scaledepth && xz || scaledepth && yz ){ // if scaledepth is set j+=(depths[h]*tmp); // scale j by width of current depth level h++; // increment h (counts through depth levels) } else j++; // otherwise, increment j by 1 } // leave y loop glColor3f( 1, 1, 1 ); // set color to white glRectf( xmax, 0, xmax+1, ymax+1 ); // draw a border right of plot glRectf( 0, ymax, xmax, ymax+1 ); // draw a border on top of plot for( i=0; i<64; i++ ){ // draw color bar glColor3f( jet[i][0], jet[i][1], jet[i][2]); // sets color k=(float)i; // turns i into a float y=(float)ymax/64; // scales rectangles to fit in ymax glRectf( xmax+10, y*k, xmax+20, (k+1)*y ); // draws rectangle } glColor3f( 1, 1, 1 ); // color to white if( logscale ) sprintf( str, "%.2f", logmx ); else sprintf( str, "%.1e", mxval ); // labels color bar with max val stroke( str, xmax+2, ymax-1 ); if( logscale ) sprintf( str, "%.2f", logmn ); else sprintf( str, "%.1e", mnval ); // labels color bar with min val stroke( str, xmax+2, 1 ); if( xz ) // in xz view sprintf( str, "N-S slice %d", yoffset+1); // labels NS slice else{ if( yz ) // in yz view sprintf( str, "E-W slice %d", xoffset+1); // labels EW slice else // in xy view sprintf( str, "Level %d", ilev ); // labels current level } stroke( str, 1, ymax+5 ); sprintf( str, "Time %d", count+1 ); // labels current time step stroke( str, xmax/2, ymax+5 ); if( glo ) // labels how max/min have been set sprintf( str, "Global" ); // if glo is set, display Global if( usr ) sprintf( str, "User-set" ); // if usr is set, display User-set if( !usr && !glo ) sprintf( str, "Local" ); // else display Local stroke( str, xmax+8, ymax+8 ); if( anim ){ // tell user if autoplay is on sprintf( str, "Autoplay" ); stroke( str, xmax-35, ymax+8 ); } if( logscale ){ sprintf( str, "Log Scale" ); // tell user if log scale is on stroke( str, xmax-25, ymax+15); } stroke( fns[q][count], 1, ymax+15 ); // labels current file glutSwapBuffers(); // double buffering set to animate smoothly glFlush(); } } void stroke( char str[], int x, int y ){ // called to display text onscreen int i; glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // sets blending mode glEnable( GL_BLEND ); // enables blending glEnable( GL_LINE_SMOOTH ); // enables smooth lines glMatrixMode( GL_MODELVIEW ); // sets matrix mode glPushMatrix(); // push matrix glScalef( SCALE, SCALE, SCALE ); // scales stroked text glTranslatef( (1/SCALE)*x, (1/SCALE)*y, 0 ); // determines location of text for( i=0; i0 ) // if down arrow key is pressed yoffset--; // in xz view, move south else{ if( yz && xoffset0 ) xoffset--; // in yz view, move west else if( ilev>1 && !xz && !yz ) ilev--; // in xy view, move up a depth level } break; case LEFT : if( count>0 ) count--; // if left arrow is pressed, move back one time step break; case RIGHT: if( count0 ) // if you haven't reached the bottom in xz view yoffset--; // go down one NS slice else{ if( yz && xoffset0 ) // if you haven't reached the edge in yz view xoffset--; // go west one EW slice else if( ilev>1 && !xz && !yz ) // if you haven't reached the top in xy view ilev--; // go up one level } break; case RIGHT : if( count0 ) // if you haven't reached the first time step count--; // go back one time step break; } glutPostRedisplay(); // redisplay with new values } void global(){ // calculates the max/min for the total data set FILE* fp; int h, i, j; for( h=0; h globalmx ) globalmx = mxval; // sets highest value to globalmx if( mnval < globalmn ) globalmn = mnval; // sets lowest value to globalmn } } void local( int i, int time, int lev ){ // calculates local max/min int j; mxval=0; mnval=100; if( xz ) readxz( data[i], fns[i][time]); // if xz view, reads new array of xz vals else{ if( yz ) readyz( data[i], fns[i][time]); // if yz view, reads new array of yz vals else readxy( data[i], fns[i][time], lev ); // if xy view, reads new array of xy vals } for( j=0; j mxval ) mxval=data[i][j]; // set largest val to mxval if( data[i][j] < mnval && data[i][j]!=0 ) mnval=data[i][j]; // set smallest nonzero val to mnval } } void readnames( char filename[] ){ // reads in list of filenames FILE* fp; int i=0, j=0; fp=fopen( filename, "r" ); // opens list of filenames while( !feof(fp) ){ // reads until the end of the file fscanf( fp, "%s", initfns[i] ); // places filename into an array of strings i++; // counts how many filenames there are } fclose( fp ); // close file sets=i-1; // saves number of initial filenames for(i=0; i=0; i-- ){ // read in data backwards, starting at the lowest depth fscanf( fp, "%d ", &depths[i] ); totaldepth+=depths[i]; // calculate total depth } fclose( fp ); // close file } void readjet(){ // read in color scale values FILE* fp; int i, j; fp=fopen( "jet.dat", "r" ); // open file containing values for( i=0; i<64; i++ ) // read in 64 sets of rgb values for( j=0; j<3; j++ ) fscanf( fp, "%f", &jet[i][j] ); fclose( fp ); // close file } void readxz( float arr[], char filename[] ){ // reads in xz values int i, j; float tmp[MAX][MAX]; FILE* fp; fp=fopen( filename, "rb" ); // open data file for( i=0; i= sets ) // if there are more subwindows than data sets glutDisplayFunc( black ); // color those windows black else // otherwise glutDisplayFunc( display ); // sets display func for subwindow glutCreateMenu( menu ); // adds a menu glutAddMenuEntry( "Local Color Scale", 1 ); // adds a menu entry glutAddMenuEntry( "Global Color Scale", 2 ); // adds a menu entry glutAddMenuEntry( "User-Set Color Scale", 3 ); // adds a menu entry glutAddMenuEntry( "Log Scale (on/off)", 4 ); // adds a menu entry glutAddMenuEntry( "Allow Negatives (on/off)", 5 ); // adds a menu entry glutAddMenuEntry( "Switch Endian (big/little) ", 6); // adds a menu entry glutAttachMenu( GLUT_RIGHT_BUTTON ); // menu called on right click } glutMainLoop(); // begin processing events return 0; }