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

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

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


Revision 1.8 - (show annotations) (download)
Fri Aug 3 14:37:15 2007 UTC (17 years, 11 months ago) by marissa
Branch: MAIN
Changes since 1.7: +19 -11 lines
File MIME type: text/plain
modified darwin.c

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 700
12 #define SCALE .06
13
14 int NX, NY, NZ;
15
16 void do_byteswap_f32( float arr[], int nel ), global(), local( int, int, int );
17 void readnames( char[] ), readarray( float[], char[], int ), readjet(), readxz( float[], char[] );
18 void readyz( float[], char[] ), readdepths( char[] );
19 void TimerFunction( int ), stroke( char[], int, int );
20
21 float data[MAX][MAX*MAX], mxval, mnval, jet[64][3];
22 float globalmx=0, globalmn=100;
23 int win[MAX], ilev=1, howmany, sets, count=0, glo=0, usr=0, anim=0, endian=0;
24 int xmax, ymax, yoffset=0, xoffset=0, yz=0, logscale=0, xz=0, nonegs=1;
25 int depths[MAX], scaledepth=0, totaldepth=0, scalecount=0;
26 char initfns[MAX][MAX], fns[MAX][MAX][MAX];
27
28 void menu( int value ){ // called when menu is opened on right click
29
30 switch( value ){
31 case 1: usr=glo=0; // unset glo & usr, sets local max/min
32 break;
33 case 2: glo=1; // enables global max/min
34 usr=0; // unsets usr
35 mxval=globalmx; // sets max to globalmx
36 mnval=globalmn; // sets min to globalmn
37 break;
38 case 3: usr=1; // switch to user-set max/min
39 glo=0; // unset glo
40 printf( "Max=" ); scanf( "%f", &mxval ); // prompt user for new max
41 printf( "Min=" ); scanf( "%f", &mnval ); // prompt user for new min
42 break;
43 case 4: logscale=( logscale+1 )%2; // switch log scale on/off
44 break;
45 case 5: nonegs=( nonegs+1 )%2; // switch allowance of negatives on/off
46 break;
47 case 6: endian=( endian+1 )%2; // switch between big/little endian
48 break;
49 }
50 glutPostRedisplay();
51 }
52
53 void display(){ // called on glutPostRedisplay
54 int i, h, ioff, q;
55 float r, g, b, k, y, j, tmp;
56 double num, logmx, logmn;
57 char str[MAX];
58
59
60 for( q=0; q<sets; q++ ){ // runs display func for each subwindow
61 glutSetWindow( win[q] ); // sets which subwindow to display to
62 glClear( GL_COLOR_BUFFER_BIT ); // background to black
63
64 if( xz ) { xmax=NX; ymax=NZ; }
65 else{
66 if( yz ){ xmax=NY; ymax=NZ; }
67 else { xmax=NX; ymax=NY; }
68 }
69
70 if( glo || usr ){ // if global or user-set max/min
71 if( xz )
72 readxz( data[q], fns[q][count] );
73 else{
74 if( yz )
75 readyz( data[q], fns[q][count] );
76 else
77 readarray( data[q], fns[q][count], ilev ); // read new array w/o calculating local max/min
78 }
79 }
80 else // if local max/min is set
81 local( q, count, ilev ); // read new array and calculate local max/min
82
83 if( logscale ){
84 if( usr ){
85 logmx=(double)mxval;
86 logmn=(double)mnval;
87 }
88 else{
89 logmx=log10( mxval );
90 logmn=log10( mnval );
91 }
92 }
93
94 if( scaledepth && xz || scaledepth && yz ) ymax=NY;
95 tmp=(float)ymax/totaldepth;
96 j=0; ioff=0; h=0; // ioff will count both i&j b/c data is 1D
97
98 while ( j<ymax ){ // cycles through y values
99 for( i=0; i<xmax; i++ ){ // cycles through x values
100 r=g=b=0; // set color values to black
101 if( data[q][ioff]==0 ); // if data=0, values stay black
102 else{
103 if( logscale ){
104 num=(double)data[q][ioff];
105 num=log10( num );
106 if( num<logmn ) num=0;
107 else{
108 if( num>logmx ) num=63;
109 else
110 num=63*( num-logmn )/( logmx-logmn );
111 }
112 }
113 else{
114 if( data[q][ioff]<mnval ) num=0; // if data is less than min, =min
115 else{
116 if( data[q][ioff]>mxval ) num=63; // if data is more than max, =max
117 else
118 num=63*( data[q][ioff]-mnval )/( mxval-mnval ); // scale num from 0-63 (not defined for 64)
119 }
120 }
121 r=jet[(int)num][0]; // set red val
122 g=jet[(int)num][1]; // set green val
123 b=jet[(int)num][2]; // set blue val
124 }
125
126 glColor3f( r, g, b ); // put r, g, b into effect
127 if( scaledepth && xz || scaledepth && yz )
128 glRectf( i, j, i+1, j+(depths[h]*tmp) );
129 else
130 glRectf( i, j, i+1, j+1 ); // draws a square for data value
131 ioff++;
132 }
133 if( scaledepth && xz || scaledepth && yz ){
134 j+=(depths[h]*tmp);
135 h++;
136 }
137 else j++;
138 }
139
140 glColor3f( 1, 1, 1 ); // set color to white
141 glRectf( xmax, 0, xmax+1, ymax+1 ); // draws a border
142 glRectf( 0, ymax, xmax, ymax+1 ); // draws a border
143 for( i=0; i<64; i++ ){ // draws color bar
144 glColor3f( jet[i][0], jet[i][1], jet[i][2]); // sets color
145 k=(float)i; // turns i into a float
146 y=(float)ymax/64; // sets height of rectangles
147 glRectf( xmax+10, y*k, xmax+20, (k+1)*y ); // draws rectangle
148 }
149 glColor3f( 1, 1, 1 ); // color to white
150
151 if( logscale )
152 sprintf( str, "%.2f", logmx );
153 else
154 sprintf( str, "%.1e", mxval ); // labels color bar with max val
155 stroke( str, xmax+2, ymax-1 );
156
157 if( logscale )
158 sprintf( str, "%.2f", logmn );
159 else
160 sprintf( str, "%.1e", mnval ); // labels color bar with min val
161 stroke( str, xmax+2, 1 );
162
163 if( xz )
164 sprintf( str, "N-S slice %d", yoffset+1);
165 else{
166 if( yz )
167 sprintf( str, "E-W slice %d", xoffset+1);
168 else
169 sprintf( str, "Level %d", ilev ); // labels current level
170 }
171 stroke( str, 1, ymax+5 );
172
173 sprintf( str, "Time %d", count+1 ); // labels current time
174 stroke( str, xmax/2, ymax+5 );
175
176 if( glo ) // labels how max/min have been set
177 sprintf( str, "Global" ); // if glo is set, display Global
178 if( usr )
179 sprintf( str, "User-set" ); // if usr is set, display User-set
180 if( !usr && !glo )
181 sprintf( str, "Local" ); // else display Local
182 stroke( str, xmax+8, ymax+8 );
183
184 if( anim ){ // tell user if autoplay is on
185 sprintf( str, "Autoplay" );
186 stroke( str, xmax-35, ymax+8 );
187 }
188
189 if( logscale ){
190 sprintf( str, "Log Scale" ); // tell user if log scale is on
191 stroke( str, xmax-25, ymax+15);
192 }
193
194 stroke( fns[q][count], 1, ymax+15 ); // labels current file
195
196 glutSwapBuffers(); // double buffering set to animate smoothly
197 glFlush();
198 }
199 }
200
201 void stroke( char str[], int x, int y ){ // called to display text onscreen
202 int i;
203
204 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
205 glEnable( GL_BLEND );
206 glEnable( GL_LINE_SMOOTH );
207 glMatrixMode( GL_MODELVIEW );
208
209 glPushMatrix();
210
211 glScalef( SCALE, SCALE, SCALE );
212 glTranslatef( (1/SCALE)*x, (1/SCALE)*y, 0 );
213
214 for( i=0; i<strlen( str ); i++) // display each character of str
215 glutStrokeCharacter( GLUT_STROKE_ROMAN, str[i] );
216
217 glPopMatrix();
218 }
219
220 void key( unsigned char key, int x, int y ){ // called on key press
221 int i, tmp;
222 char fn[MAX];
223
224 switch(key){
225 case 'q': exit(0); // quits on 'q'
226 break;
227 case 'r': count=0; // resets back to first time
228 ilev=1; // and first level
229 xz=yz=0;
230 break;
231 case 'a': anim=(anim+1)%2; // turns anim on/off
232 break;
233 case 'x': xz=(xz+1)%2;
234 yz=0;
235 break;
236 case 'y': yz=(yz+1)%2;
237 xz=0;
238 break;
239 case 'z': if( xz || yz ){
240 scaledepth=( scaledepth+1 )%2;
241 scalecount++;
242 if( scalecount==1 ){
243 printf( "Please enter filename containing depth data: " );
244 scanf( "%s", fn );
245 readdepths( fn );
246 }
247 }
248 break;
249 }
250 glutPostRedisplay();
251 }
252
253 void TimerFunction( int value ){ // called when anim is set and arrow key is pressed
254 int i;
255
256 switch(value){ // increments in the correct direction
257 case DOWN : if( xz && yoffset>0 )
258 yoffset--;
259 else{
260 if( yz && xoffset<NX-1 )
261 xoffset++;
262 else
263 if( ilev<NZ && !xz && !yz )
264 ilev++; // if down arrow pressed, move down a level
265 }
266 break;
267 case UP : if( xz && yoffset<NY-1 )
268 yoffset++;
269 else{
270 if( yz && xoffset>0 )
271 xoffset--;
272 else
273 if( ilev>1 && !xz && !yz )
274 ilev--; // if up arrow is pressed, move up a level
275 }
276 break;
277 case LEFT : if( count>0 )
278 count--; // if left arrow is pressed, move back one time step
279 break;
280 case RIGHT: if( count<howmany-1 )
281 count++; // if right arrow is pressed, moves forward one time step
282 break;
283 }
284
285 glutPostRedisplay();
286
287 if ( anim )
288 switch( value ){
289 case DOWN : if( xz && yoffset==0 )
290 yoffset=NY-1;
291 else{
292 if( yz && xoffset==NX-1 )
293 xoffset=0;
294 else
295 if( ilev==NZ && !xz && !yz )
296 ilev=1; // if end reached, restart
297 }
298 glutTimerFunc( 100, TimerFunction, value ); // recalls itself
299 break;
300 case UP : if( xz && yoffset==NY-1 )
301 yoffset=0;
302 else{
303 if( yz && xoffset==0 )
304 xoffset=NX-1;
305 else
306 if( ilev==1 )
307 ilev=NZ; // if end reached, restart
308 }
309 glutTimerFunc( 100, TimerFunction, value ); // recalls itself
310 break;
311 case LEFT : if( count==0 ) count=howmany-1; // if end reached, restart
312 glutTimerFunc( 100, TimerFunction, value ); // recalls itself
313 break;
314 case RIGHT: if( count==howmany-1 ) count=0; // if end reached, restart
315 glutTimerFunc( 100, TimerFunction, value ); // recalls itself
316 break;
317 }
318 }
319
320 void specialkey( int key, int x, int y ){
321 int i;
322
323 if( anim ) // if animation is set, call the timer function
324 glutTimerFunc( 100, TimerFunction, key); // to scroll automatically
325
326 switch(key){
327 case DOWN : if( xz && yoffset>0 )
328 yoffset--;
329 else{
330 if( yz && xoffset<NY-1 )
331 xoffset++;
332 else
333 if( ilev<NZ && !xz && !yz ) // if you haven't reached the bottom
334 ilev++; // keep going down
335 }
336 break;
337 case UP : if( xz && yoffset<NY-1 )
338 yoffset++;
339 else{
340 if( yz && xoffset>0 )
341 xoffset--;
342 else
343 if( ilev>1 ) // if you haven't reached the top
344 ilev--; // keep going up
345 }
346 break;
347 case RIGHT : if( count<howmany-1 ) // if you haven't reached the last file
348 count++; // keep going right
349 break;
350 case LEFT : if( count>0 ) // if you haven't reached the first file
351 count--; // keep going left
352 break;
353 }
354 glutPostRedisplay();
355 }
356
357 void global(){ // calculates the max/min for the total data set
358 FILE* fp;
359 int h, i, j;
360 for( h=0; h<sets; h++) // cycles through each window
361 for( i=0; i<howmany; i++ ) // cycles through each time
362 for( j=0; j<NZ; j++ ){ // cycles through each level for each file
363 local( h, i, j ); // calculates local max/min for specific data set
364 if( mxval > globalmx ) globalmx = mxval; // sets highest value to globalmx
365 if( mnval < globalmn ) globalmn = mnval; // sets lowest value to globalmn
366 }
367 }
368
369 void local( int i, int time, int lev ){ // calculates local max/min
370 int j;
371
372 mxval=0;
373 mnval=100;
374 if( xz )
375 readxz( data[i], fns[i][time]);
376 else{
377 if( yz )
378 readyz( data[i], fns[i][time]);
379 else
380 readarray( data[i], fns[i][time], lev ); // read new array of data
381 }
382 for( j=0; j<xmax*ymax; j++ ){
383 if( data[i][j] > mxval )
384 mxval=data[i][j]; // set largest val to mxval
385 if( data[i][j] < mnval && data[i][j]!=0 )
386 mnval=data[i][j]; // set smallest positive val to mnval
387 }
388 }
389
390 void readnames( char filename[] ){ // reads in list of filenames
391 FILE* fp;
392 int i=0, j=0;
393
394 fp=fopen( filename, "r" ); // opens list of filenames
395 while( !feof(fp) ){ // reads until the end of the file
396 fscanf( fp, "%s", initfns[i] ); // places filename into an array of strings
397 i++; // counts how many filenames there are
398 }
399 fclose( fp ); // close file
400 sets=i-1; // saves number of initial filenames
401
402 for(i=0; i<sets; i++){ // goes through each read-in filename
403 fp=fopen( initfns[i], "r" ); // opens each filename
404 j=0;
405 while( !feof(fp) ){ // reads in filenames from each filename
406 fscanf( fp, "%s", fns[i][j]);
407 j++;
408 }
409 fclose(fp); // close file
410 }
411 howmany=j-1; // saves number of data filenames
412 }
413
414 void readdepths( char filename[] ){
415 int i;
416 FILE* fp;
417
418 fp=fopen( filename, "r" );
419
420 for( i=NZ-1; i>=0; i-- ){
421 fscanf( fp, "%d ", &depths[i] );
422 totaldepth+=depths[i];
423 }
424
425 fclose( fp );
426 }
427
428 void readjet(){ //reads in color scale values
429 FILE* fp;
430 int i, j;
431
432 fp=fopen( "jet.dat", "r" ); // opens file containing values
433 for( i=0; i<64; i++ ) // reads in 64 sets of r, g, b values
434 for( j=0; j<3; j++ )
435 fscanf( fp, "%f", &jet[i][j] );
436 fclose( fp ); // closes file
437 }
438
439 void readxz( float arr[], char filename[] ){
440 int i, j;
441 float tmp[MAX][MAX], tmp2[MAX*MAX];
442 FILE* fp;
443
444 fp=fopen( filename, "rb" );
445 for( i=0; i<NZ; i++){
446 fseek( fp, (NX*yoffset*4)+(i*NX*NY*4), SEEK_SET );
447 fread( &arr[NX*i], sizeof( arr[0] ), NX, fp ); // reads in data to fill one level
448 }
449 fclose( fp );
450
451 for( i=0; i<NZ; i++ )
452 for( j=0; j<NX; j++)
453 tmp[i][j]=arr[i*NX+j];
454
455 for( i=0; i<NZ; i++ )
456 for( j=0; j<NX; j++)
457 tmp2[i*NX+j]=tmp[NZ-i-1][j];
458
459 for( i=0; i<NX*NZ; i++)
460 arr[i]=tmp2[i];
461 }
462
463 void readyz( float arr[], char filename[] ){
464 int i, j;
465 float tmp[MAX][MAX], tmp2[MAX*MAX];
466 FILE* fp;
467
468 fp=fopen( filename, "rb" );
469 for( i=0; i<NY*NZ; i++ ){
470 fseek( fp, (xoffset*4)+(i*NX*4), SEEK_SET );
471 fread( &arr[i], sizeof( arr[0] ), 1, fp );
472 }
473 fclose(fp);
474
475 for( i=0; i<NZ; i++ )
476 for( j=0; j<NY; j++)
477 tmp[i][j]=arr[i*NY+j];
478
479 for( i=0; i<NZ; i++ )
480 for( j=0; j<NY; j++)
481 tmp2[i*NY+j]=tmp[NZ-i-1][j];
482
483 for( i=0; i<NY*NZ; i++)
484 arr[i]=tmp2[i];
485 }
486
487 void readarray( float arr[], char filename[], int il ){ // reads new data
488 FILE* fp;
489 int i;
490
491 fp=fopen( filename, "rb" ); // opens the file containing data
492 fseek( fp, (il-1)*NX*NY*4, SEEK_SET ); // seeks to the correct place using ilev
493 fread( arr, sizeof( arr[0] ), NX*NY, fp ); // reads in data to fill one level
494 fclose( fp ); // close file
495
496 if( nonegs )
497 for( i=0; i<NX*NY; i++ )
498 if( arr[i] < 0 )
499 arr[i] = pow(10, -20); // sets negative values to 10^-20
500
501 if( endian )
502 do_byteswap_f32( arr, NX*NY ); // switches endian
503 }
504
505 void do_byteswap_f32( float arr[], int nel ){ // switches endian
506
507 int i;
508 char src[4], trg[4];
509
510 for( i=0; i<nel; i++ ){
511 memcpy( src, &(arr[i]), 4 );
512 trg[0]=src[3];
513 trg[1]=src[2];
514 trg[2]=src[1];
515 trg[3]=src[0];
516 memcpy( &(arr[i]), trg, 4 );
517 }
518 }
519
520 void black( ){
521 glClear( GL_COLOR_BUFFER_BIT );
522 glutSwapBuffers();
523 glFlush();
524 }
525
526
527 int main( int argc, char *argv[] ){
528 int i, setsx, setsy, tmpx, tmpy, winx, winy, parent;
529 char str[MAX], filename[MAX];
530 FILE* fp;
531
532 if( strcmp(argv[1], "binary") == 0 )
533 fp=fopen( ".darwinview/binconfig", "r" );
534 else
535 if( strcmp(argv[1],"netcdf") == 0 )
536 fp=fopen( ".darwinview/ncconfig", "r" );
537
538 fscanf( fp, "%dx%d ", &winx, &winy );
539 winy-=60; winx-=20; // adjusts resolution so edges won't get cut off
540 fscanf( fp, "%d %d %d ", &NX, &NY, &NZ );
541 fscanf( fp, "%dx%d ", &setsx, &setsy ); // prompts user for dimensions of subwindows
542 fscanf( fp, "%s", filename );
543
544 fclose( fp );
545
546 xmax=NX; ymax=NY;
547
548 readjet(); // stores color values
549 readnames( filename ); // gets list of filenames to read from
550 global(); // calculates max and min for all data
551
552 glutInit( &argc, argv );
553 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); // sets rgb mode and double buffering
554 glutInitWindowSize( winx, winy ); // parent window will cover screen
555 glutInitWindowPosition( 10, 10 ); // location of parent window
556 parent=glutCreateWindow( WINDOW ); // creates parent window
557
558 glClearColor( 0, 0, 0, 0 ); // sets clear color to black
559 gluOrtho2D( 0, winx , winy, 0 ); // sets(0,0) as top left corner
560 glutDisplayFunc( display );
561 glutKeyboardFunc( key ); // called on key press
562 glutSpecialFunc( specialkey ); // called on special key press (arrow keys)
563
564
565 for( i=0; i<setsx*setsy; i++ ){
566 tmpx = (i%setsx)*(winx/setsx); // x coordinate of top left corner of subwindow
567 tmpy = (i/setsx)*(winy/setsy); // y coordinate of top left corner of subwindow
568
569 win[i]=glutCreateSubWindow( parent, tmpx, tmpy, winx/setsx, winy/setsy ); // creates subwindow
570 gluOrtho2D( 0, NX+35, 0, NY+25 ); // sets how data is mapped to subwindow
571 glutKeyboardFunc( key ); // called on key press
572 glutSpecialFunc( specialkey ); // called on special key press (arrow keys)
573 if( i >= sets ) //
574 glutDisplayFunc( black );
575 else
576 glutDisplayFunc( display ); // sets display func for subwindow
577
578
579 glutCreateMenu( menu ); // adds a menu
580 glutAddMenuEntry( "Local Color Scale", 1 ); // adds a menu entry
581 glutAddMenuEntry( "Global Color Scale", 2 ); // adds a menu entry
582 glutAddMenuEntry( "User-Set Color Scale", 3 ); // adds a menu entry
583 glutAddMenuEntry( "Log Scale (on/off)", 4 ); // adds a menu entry
584 glutAddMenuEntry( "Allow Negatives (on/off)", 5 ); // adds a menu entry
585 glutAddMenuEntry( "Switch Endian (big/little) ", 6); // adds a menu entry
586 glutAttachMenu( GLUT_RIGHT_BUTTON ); // menu called on right click
587 }
588
589 glutMainLoop(); // begin processing events
590 return 0;
591 }
592

  ViewVC Help
Powered by ViewVC 1.1.22