/[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.5 - (hide annotations) (download)
Mon Jul 16 19:16:26 2007 UTC (17 years, 11 months ago) by marissa
Branch: MAIN
Changes since 1.4: +112 -51 lines
File MIME type: text/plain
yz capability!

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

  ViewVC Help
Powered by ViewVC 1.1.22