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

  ViewVC Help
Powered by ViewVC 1.1.22