/[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.10 - (show annotations) (download)
Thu Jan 8 13:34:48 2009 UTC (15 years, 3 months ago) by cnh
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +9 -2 lines
File MIME type: text/plain
Fixes to prototype for Basant.

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

  ViewVC Help
Powered by ViewVC 1.1.22