#include #include #include #include #include #define WINDOW "image" #define UP 101 #define DOWN 103 #define RIGHT 102 #define LEFT 100 #define MAX 700 #define SCALE .06 int NX, NY, NZ; void do_byteswap_f32( float arr[], int nel ), global(), local( int, int, int ); void readnames( char[] ), readarray( float[], char[], int ), readjet(), readxz( float[], char[] ); void readyz( float[], char[] ), readdepths( char[] ); void TimerFunction( int ), stroke( char[], int, int ); float data[MAX][MAX*MAX], mxval, mnval, jet[64][3]; float globalmx=0, globalmn=100; int win[MAX], ilev=1, howmany, sets, count=0, glo=0, usr=0, anim=0, endian=0; int xmax, ymax, yoffset=0, xoffset=0, yz=0, logscale=0, xz=0, nonegs=1; int depths[MAX], scaledepth=0, 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; // switch log scale on/off break; case 5: nonegs=( nonegs+1 )%2; // switch allowance of negatives on/off break; case 6: endian=( endian+1 )%2; // switch between big/little endian break; } glutPostRedisplay(); } 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; else num=63*( num-logmn )/( logmx-logmn ); } } else{ if( data[q][ioff]mxval ) num=63; // if data is more than max, =max else num=63*( data[q][ioff]-mnval )/( mxval-mnval ); // scale num from 0-63 (not defined for 64) } } r=jet[(int)num][0]; // set red val g=jet[(int)num][1]; // set green val b=jet[(int)num][2]; // set blue val } glColor3f( r, g, b ); // put r, g, b into effect if( scaledepth && xz || scaledepth && yz ) glRectf( i, j, i+1, j+(depths[h]*tmp) ); else glRectf( i, j, i+1, j+1 ); // draws a square for data value ioff++; } if( scaledepth && xz || scaledepth && yz ){ j+=(depths[h]*tmp); h++; } else j++; } glColor3f( 1, 1, 1 ); // set color to white glRectf( xmax, 0, xmax+1, ymax+1 ); // draws a border glRectf( 0, ymax, xmax, ymax+1 ); // draws a border for( i=0; i<64; i++ ){ // draws 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; // sets height of rectangles 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 ) sprintf( str, "N-S slice %d", yoffset+1); else{ if( yz ) sprintf( str, "E-W slice %d", xoffset+1); else sprintf( str, "Level %d", ilev ); // labels current level } stroke( str, 1, ymax+5 ); sprintf( str, "Time %d", count+1 ); // labels current time 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 ); glEnable( GL_BLEND ); glEnable( GL_LINE_SMOOTH ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glScalef( SCALE, SCALE, SCALE ); glTranslatef( (1/SCALE)*x, (1/SCALE)*y, 0 ); for( i=0; i0 ) yoffset--; else{ if( yz && xoffset0 ) xoffset--; else if( ilev>1 && !xz && !yz ) ilev--; // if up arrow is pressed, move up a level } break; case LEFT : if( count>0 ) count--; // if left arrow is pressed, move back one time step break; case RIGHT: if( count0 ) yoffset--; else{ if( yz && xoffset0 ) xoffset--; else if( ilev>1 ) // if you haven't reached the top ilev--; // keep going up } break; case RIGHT : if( count0 ) // if you haven't reached the first file count--; // keep going left break; } glutPostRedisplay(); } 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]); else{ if( yz ) readyz( data[i], fns[i][time]); else readarray( data[i], fns[i][time], lev ); // read new array of data } 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 positive 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-- ){ fscanf( fp, "%d ", &depths[i] ); totaldepth+=depths[i]; } fclose( fp ); } void readjet(){ //reads in color scale values FILE* fp; int i, j; fp=fopen( "jet.dat", "r" ); // opens file containing values for( i=0; i<64; i++ ) // reads in 64 sets of r, g, b values for( j=0; j<3; j++ ) fscanf( fp, "%f", &jet[i][j] ); fclose( fp ); // closes file } void readxz( float arr[], char filename[] ){ int i, j; float tmp[MAX][MAX], tmp2[MAX*MAX]; FILE* fp; fp=fopen( filename, "rb" ); for( i=0; i= sets ) // glutDisplayFunc( black ); else 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; }