/[MITgcm]/MITgcm_contrib/darwinview/src/darwin.c
ViewVC logotype

Annotation of /MITgcm_contrib/darwinview/src/darwin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (hide annotations) (download)
Fri Jul 13 18:47:12 2007 UTC (17 years, 11 months ago) by marissa
Branch: MAIN
Changes since 1.2: +73 -52 lines
File MIME type: text/plain
modifications galore!

1 marissa 1.1 #include <GL/glut.h>
2     #include <stdlib.h>
3     #include <stdio.h>
4     #include <string.h>
5     #include <math.h>
6     #define WINDOW "image"
7     #define UP 101
8     #define DOWN 103
9     #define RIGHT 102
10     #define LEFT 100
11     #define MAX 200
12    
13 marissa 1.3 int NX, NY, NZ;
14 marissa 1.1
15     void do_byteswap_f32( float arr[], int nel ), global(), local( int, int, int );
16     void readnames( char[] ), readarray( float[], char[], int ), readjet();
17     void TimerFunction( int ), bitmap( char[], int, int );
18    
19     float data[MAX][MAX*MAX], mxval, mnval, jet[MAX][MAX];
20     float globalmx=0, globalmn=100;
21 marissa 1.3 int win[MAX], ilev=1, howmany, sets, count=0, glo=0, usr=0, anim=0, logscale=0, nonegs=1, endian=0;
22 marissa 1.1 char initfns[MAX][MAX], fns[MAX][MAX][MAX];
23    
24 marissa 1.2 void menu(int value){ // called when menu is opened on right click
25 marissa 1.1
26     switch( value ){
27 marissa 1.2 case 1: usr=glo=0; // unset glo & usr, sets local max/min
28     glutPostRedisplay(); // recall display func with new values
29 marissa 1.1 break;
30 marissa 1.2 case 2: glo=1; // enables global max/min
31     usr=0; // unsets usr
32     mxval=globalmx; // sets max to globalmx
33     mnval=globalmn; // sets min to globalmn
34     glutPostRedisplay(); // recall display func with new values
35 marissa 1.1 break;
36 marissa 1.2 case 3: usr=1; // switch to user-set max/min
37     glo=0; // unset glo
38     printf( "Max=" ); scanf( "%f", &mxval ); // prompt user for new max
39     printf( "Min=" ); scanf( "%f", &mnval ); // prompt user for new min
40     glutPostRedisplay(); // recall display func with new values
41     break;
42     case 4: logscale=(logscale+1)%2; // switch log scale on/off
43     glutPostRedisplay();
44 marissa 1.1 break;
45 marissa 1.3 case 5: nonegs=(nonegs+1)%2; // switch allowance of negatives on/off
46     glutPostRedisplay();
47     break;
48     case 6: endian=(endian+1)%2; // switch between big/little endian
49     glutPostRedisplay();
50     break;
51 marissa 1.1 }
52     }
53 marissa 1.2 void display(void){ // called on glutPostRedisplay
54 marissa 1.1 int i, j, ioff, q;
55 marissa 1.2 float r, g, b, k, y;
56     double num, logmx, logmn;
57 marissa 1.1 char str[MAX];
58    
59 marissa 1.3 for( q=0; q<sets; q++ ){ // runs display func for each subwindow
60 marissa 1.2 glutSetWindow( win[q] ); // sets which subwindow to display to
61     glClear( GL_COLOR_BUFFER_BIT ); // background to black
62     if( glo || usr ) // if global or user-set max/min
63     readarray( data[q], fns[q][count], ilev ); // read new array w/o calculating local max/min
64     else // if local max/min is set
65     local( q, count, ilev ); // read new array and calculate local max/min
66    
67     if( logscale ){
68     if( usr ){
69     logmx=(double)mxval;
70     logmn=(double)mnval;
71     }
72     else{
73     logmx=log10( mxval );
74     logmn=log10( mnval );
75     }
76     }
77    
78     ioff=0; // ioff will count both i&j b/c data is 1D
79     for( j=0; j<NY; j++ ){ // cycles through y values
80     for( i=0; i<NX; i++ ){ // cycles through x values
81     r=g=b=0; // set color values to black
82     if( data[q][ioff]==0 ); // if data=0, values stay black
83 marissa 1.1 else{
84 marissa 1.2 if( logscale ){
85     num=(double)data[q][ioff];
86     num=log10( num );
87     if( num<logmn ) num=0;
88 marissa 1.3 else{
89     if( num>logmx ) num=63;
90     else
91     num=63*( num-logmn )/( logmx-logmn );
92     }
93 marissa 1.2 }
94 marissa 1.1 else{
95 marissa 1.2 if( data[q][ioff]<mnval ) num=0; // if data is less than min, =min
96 marissa 1.3 else{
97 marissa 1.2 if( data[q][ioff]>mxval ) num=63; // if data is more than max, =max
98     else
99     num=63*( data[q][ioff]-mnval )/( mxval-mnval ); // scale num from 0-63 (not defined for 64)
100 marissa 1.3 }
101 marissa 1.1 }
102 marissa 1.2 r=jet[(int)num][0]; // set red val
103     g=jet[(int)num][1]; // set green val
104     b=jet[(int)num][2]; // set blue val
105 marissa 1.1 }
106 marissa 1.2
107     glColor3f( r, g, b ); // put r, g, b into effect
108     glRectf( i, j, i+1, j+1 ); // draws a square for data value
109 marissa 1.1 ioff++;
110     }
111     }
112 marissa 1.2 glColor3f( 1, 1, 1 ); // set color to white
113     glRectf( NX, 0, NX+1, NY+1 ); // draws a border
114     glRectf( 0, NY, NX, NY+1 ); // draws a border
115     for( i=0; i<64; i++ ){ // draws color bar
116     glColor3f( jet[i][0], jet[i][1], jet[i][2]); // sets color
117     k=(float)i; // turns i into a float
118     y=(float)NY/64; // sets height of rectangles
119     glRectf( NX+10, y*k, NX+20, (k+1)*y ); // draws rectangle
120 marissa 1.1 }
121 marissa 1.2 glColor3f( 1, 1, 1 ); // color to white
122 marissa 1.1
123 marissa 1.2 if( logscale )
124     sprintf( str, "%.2f", logmx );
125     else
126 marissa 1.3 sprintf( str, "%.1e", mxval ); // labels color bar with max val
127 marissa 1.1 bitmap( str, NX+2, NY-1 );
128    
129 marissa 1.2 if( logscale )
130     sprintf( str, "%.2f", logmn );
131     else
132 marissa 1.3 sprintf( str, "%.1e", mnval ); // labels color bar with min val
133 marissa 1.1 bitmap( str, NX+2, 1 );
134    
135 marissa 1.2 sprintf( str, "Level %d", ilev ); // labels current level
136     bitmap( str, 1, NY+3 );
137 marissa 1.1
138 marissa 1.2 sprintf( str, "Time %d", count+1 ); // labels current time
139     bitmap( str, 50, NY+3 );
140    
141     if( glo ) // labels how max/min have been set
142     sprintf( str, "Global" ); // if glo is set, display Global
143 marissa 1.1 if( usr )
144 marissa 1.2 sprintf( str, "User-set" ); // if usr is set, display User-set
145 marissa 1.1 if( !usr && !glo )
146 marissa 1.2 sprintf( str, "Local" ); // else display Local
147     bitmap( str, NX+12, NY+3 );
148 marissa 1.1
149 marissa 1.2 if( anim ){ // tell user if autoplay is on
150 marissa 1.1 sprintf( str, "Autoplay" );
151 marissa 1.2 bitmap( str, NX-25, NY+3 );
152     }
153    
154     if( logscale ){
155     sprintf( str, "Log Scale" ); // tell user if log scale is on
156     bitmap( str, NX-25, NY+10 );
157 marissa 1.1 }
158    
159 marissa 1.2 bitmap( fns[q][count], 1, NY+10 ); // labels current file
160 marissa 1.1
161 marissa 1.2 glutSwapBuffers(); // double buffering set to animate smoothly
162 marissa 1.1 glFlush();
163     }
164     }
165    
166 marissa 1.2 void bitmap( char str[], int x, int y ){ // called to display text onscreen
167 marissa 1.1 int i;
168    
169 marissa 1.2 glRasterPos2f( x, y ); // set position of text
170     for( i=0; i<strlen( str ); i++) // display each character of str
171 marissa 1.1 glutBitmapCharacter( GLUT_BITMAP_HELVETICA_12, str[i] );
172     }
173    
174 marissa 1.2 void key( unsigned char key, int x, int y ){ // called on key press
175 marissa 1.3 int i, tmp;
176 marissa 1.1
177     switch(key){
178 marissa 1.2 case 'q': exit(0); // quits on 'q'
179 marissa 1.1 break;
180 marissa 1.2 case 'r': count=0; // resets back to first time
181     ilev=1; // and first level
182 marissa 1.1 glutPostRedisplay();
183     break;
184 marissa 1.2 case 'a': anim=(anim+1)%2; // turns anim on/off
185 marissa 1.1 glutPostRedisplay();
186     break;
187     }
188     }
189    
190 marissa 1.2 void TimerFunction( int value ){ // called when anim is set and arrow key is pressed
191 marissa 1.1 int i;
192    
193 marissa 1.2 switch(value){ // increments in the correct direction
194 marissa 1.3 case DOWN : if( ilev<NZ )
195 marissa 1.2 ilev++; // if down arrow pressed, move down a level
196 marissa 1.1 break;
197     case UP : if( ilev>1 )
198 marissa 1.2 ilev--; // if up arrow is pressed, move up a level
199 marissa 1.1 break;
200     case LEFT : if( count>0 )
201 marissa 1.2 count--; // if left arrow is pressed, move back one time step
202 marissa 1.1 break;
203     case RIGHT: if( count<howmany-1 )
204 marissa 1.2 count++; // if right arrow is pressed, moves forward one time step
205 marissa 1.1 break;
206     }
207    
208     glutPostRedisplay();
209    
210     if (anim )
211     switch( value ){
212 marissa 1.3 case DOWN : if( ilev==NZ ) ilev=1; // if end reached, restart
213 marissa 1.1 glutTimerFunc( 100, TimerFunction, value ); // recalls itself
214     break;
215 marissa 1.3 case UP : if( ilev==1 ) ilev=NZ; // if end reached, restart
216 marissa 1.1 glutTimerFunc( 100, TimerFunction, value ); // recalls itself
217     break;
218 marissa 1.2 case LEFT : if( count==0 ) count=howmany-1; // if end reached, restart
219 marissa 1.1 glutTimerFunc( 100, TimerFunction, value ); // recalls itself
220     break;
221 marissa 1.2 case RIGHT: if( count==howmany-1 ) count=0; // if end reached, restart
222 marissa 1.1 glutTimerFunc( 100, TimerFunction, value ); // recalls itself
223     break;
224     }
225     }
226    
227     void specialkey( int key, int x, int y ){
228     int i;
229    
230 marissa 1.2 if( anim ) // if animation is set, call the timer function
231     glutTimerFunc( 100, TimerFunction, key); // to scroll automatically
232 marissa 1.1
233     switch(key){
234 marissa 1.3 case DOWN : if( ilev<NZ ) // if you haven't reached the bottom
235 marissa 1.2 ilev++; // keep going down
236 marissa 1.1 break;
237 marissa 1.2 case UP : if( ilev>1 ) // if you haven't reached the top
238     ilev--; // keep going up
239 marissa 1.1 break;
240     case RIGHT : if( count<howmany-1 ) // if you haven't reached the last file
241     count++; // keep going right
242     break;
243     case LEFT : if( count>0 ) // if you haven't reached the first file
244     count--; // keep going left
245     break;
246     }
247     glutPostRedisplay();
248     }
249    
250 marissa 1.2 void global(){ // calculates the max/min for the total data set
251 marissa 1.1 FILE* fp;
252     int h, i, j;
253 marissa 1.3 for( h=0; h<sets; h++) // cycles through each window
254 marissa 1.2 for( i=0; i<howmany; i++ ) // cycles through each time
255 marissa 1.3 for( j=0; j<NZ; j++ ){ // cycles through each level for each file
256 marissa 1.2 local( h, i, j ); // calculates local max/min for specific data set
257 marissa 1.1 if( mxval > globalmx ) globalmx = mxval; // sets highest value to globalmx
258     if( mnval < globalmn ) globalmn = mnval; // sets lowest value to globalmn
259     }
260     }
261    
262 marissa 1.2 void local( int i, int time, int lev ){ // calculates local max/min
263 marissa 1.1 int j;
264    
265     mxval=0;
266     mnval=100;
267 marissa 1.2 readarray( data[i], fns[i][time], lev ); // read new array of data
268 marissa 1.1 for( j=0; j<NX*NY; j++ ){
269 marissa 1.2 if( data[i][j] > mxval )
270     mxval=data[i][j]; // set largest val to mxval
271 marissa 1.3 if( data[i][j] < mnval && data[i][j]!=0 )
272 marissa 1.2 mnval=data[i][j]; // set smallest positive val to mnval
273 marissa 1.1 }
274     }
275    
276 marissa 1.2 void readnames( char filename[] ){ // reads in list of filenames
277 marissa 1.1 FILE* fp;
278     int i=0, j=0;
279    
280 marissa 1.2 fp=fopen( filename, "r" ); // opens list of filenames
281     while( !feof(fp) ){ // reads until the end of the file
282     fscanf( fp, "%s", initfns[i] ); // places filename into an array of strings
283     i++; // counts how many filenames there are
284 marissa 1.1 }
285 marissa 1.2 fclose( fp ); // close file
286 marissa 1.3 sets=i-1; // saves number of initial filenames
287 marissa 1.1
288 marissa 1.3 for(i=0; i<sets; i++){ // goes through each read-in filename
289 marissa 1.2 fp=fopen( initfns[i], "r" ); // opens each filename
290 marissa 1.1 j=0;
291 marissa 1.2 while( !feof(fp) ){ // reads in filenames from each filename
292     fscanf( fp, "%s", fns[i][j]);
293 marissa 1.1 j++;
294     }
295 marissa 1.2 fclose(fp); // close file
296 marissa 1.1 }
297 marissa 1.2 howmany=j-1; // saves number of data filenames
298 marissa 1.1 }
299    
300 marissa 1.2 void readjet(){ //reads in color scale values
301 marissa 1.1 FILE* fp;
302     int i, j;
303    
304     fp=fopen( "jet.dat", "r" ); // opens file containing values
305 marissa 1.2 for( i=0; i<64; i++ ) // reads in 64 sets of r, g, b values
306 marissa 1.1 for( j=0; j<3; j++ )
307     fscanf( fp, "%f", &jet[i][j] );
308 marissa 1.2 fclose( fp ); // closes file
309 marissa 1.1 }
310    
311     void readarray( float arr[], char filename[], int il ){ // reads new data
312 marissa 1.3 FILE* fp;
313 marissa 1.1 int i;
314    
315 marissa 1.2 fp=fopen( filename, "r" ); // opens the file containing data
316     fseek( fp, (il-1)*NX*NY*4, SEEK_SET ); // seeks to the correct place using ilev
317 marissa 1.1 fread( arr, sizeof( arr[0] ), NX*NY, fp ); // reads in data to fill one level
318 marissa 1.2 fclose( fp ); // close file
319    
320 marissa 1.3 if( nonegs )
321     for( i=0; i<NX*NY; i++ )
322     if( arr[i] < 0 )
323     arr[i] = pow(10, -20); // sets negative values to 10^-20
324    
325     if( endian )
326     do_byteswap_f32( arr, NX*NY ); // switches endian
327 marissa 1.1 }
328    
329 marissa 1.3 void do_byteswap_f32( float arr[], int nel ){ // switches endian
330    
331     int i;
332     char src[4], trg[4];
333    
334     for( i=0; i<nel; i++ ){
335     memcpy( src, &(arr[i]), 4 );
336     trg[0]=src[3];
337     trg[1]=src[2];
338     trg[2]=src[1];
339     trg[3]=src[0];
340     memcpy( &(arr[i]), trg, 4 );
341     }
342     }
343    
344     void black(){
345     glClear( GL_COLOR_BUFFER_BIT );
346     glutSwapBuffers();
347     glFlush();
348 marissa 1.1 }
349    
350     int main( int argc, char *argv[] ){
351 marissa 1.3 int i, setsx, setsy, tmpx, tmpy, winx, winy, parent;
352 marissa 1.1 char filename[MAX];
353    
354 marissa 1.3 sscanf( argv[1], "%dx%d", &winx, &winy ); // reads screen resolution from command line
355 marissa 1.2 winy-=60; winx-=20; // adjusts resolution so edges won't get cut off
356 marissa 1.1
357     printf( "Please enter x, y and z dimensions.\n" );
358 marissa 1.3 scanf( "%d %d %d", &NX, &NY, &NZ ); // prompts user for NX, NY, NZ
359 marissa 1.1 printf( "Please enter filename.\n" );
360 marissa 1.2 scanf( "%s", filename ); // prompts user for initial filenames
361 marissa 1.1 printf( "Please enter dimensions of data sets.\n" );
362 marissa 1.3 scanf( "%dx%d", &setsx, &setsy ); // prompts user for dimensions of subwindows
363 marissa 1.1
364 marissa 1.2 readjet(); // stores color values
365     readnames( filename ); // gets list of filenames to read from
366     global(); // calculates max and min for all data
367    
368     glutInit( &argc, argv );
369     glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); // sets rgb mode and double buffering
370     glutInitWindowSize( winx, winy ); // parent window will cover screen
371     glutInitWindowPosition( 10, 10 ); // location of parent window
372     parent=glutCreateWindow( WINDOW ); // creates parent window
373 marissa 1.1
374 marissa 1.2 glClearColor( 0, 0, 0, 0 ); // sets clear color to black
375     gluOrtho2D( 0, winx , winy, 0 ); // sets(0,0) as top left corner
376 marissa 1.1 glutDisplayFunc( display );
377 marissa 1.2 glutKeyboardFunc( key ); // called on key press
378     glutSpecialFunc( specialkey ); // called on special key press (arrow keys)
379 marissa 1.3
380 marissa 1.1
381     for( i=0; i<setsx*setsy; i++ ){
382 marissa 1.2 tmpx = (i%setsx)*(winx/setsx); // x coordinate of top left corner of subwindow
383     tmpy = (i/setsx)*(winy/setsy); // y coordinate of top left corner of subwindow
384 marissa 1.1
385 marissa 1.2 win[i]=glutCreateSubWindow( parent, tmpx, tmpy, winx/setsx, winy/setsy ); // creates subwindow
386     gluOrtho2D( 0, NX+35, 0, NY+15 ); // sets how data is mapped to subwindow
387     glutKeyboardFunc( key ); // called on key press
388     glutSpecialFunc( specialkey ); // called on special key press (arrow keys)
389 marissa 1.3 if( i >= sets ) //
390     glutDisplayFunc( black );
391     else
392     glutDisplayFunc( display ); // sets display func for subwindow
393    
394 marissa 1.2
395 marissa 1.3 glutCreateMenu( menu ); // adds a menu
396     glutAddMenuEntry( "Local Color Scale", 1 ); // adds a menu entry
397     glutAddMenuEntry( "Global Color Scale", 2 ); // adds a menu entry
398     glutAddMenuEntry( "User-Set Color Scale", 3 ); // adds a menu entry
399     glutAddMenuEntry( "Log Scale (on/off)", 4 ); // adds a menu entry
400     glutAddMenuEntry( "Allow Negatives (on/off)", 5 ); // adds a menu entry
401     glutAddMenuEntry( "Switch Endian (big/little) ", 6); // adds a menu entry
402     glutAttachMenu( GLUT_RIGHT_BUTTON ); // menu called on right click
403 marissa 1.1 }
404    
405 marissa 1.2 glutMainLoop(); // begin processing events
406 marissa 1.1 return 0;
407     }
408    

  ViewVC Help
Powered by ViewVC 1.1.22