home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / coven / glpv-1.1.tgz / glpv-1.1.tar / glpv / glpv.c < prev    next >
C/C++ Source or Header  |  2003-01-28  |  24KB  |  976 lines

  1. /*
  2.  * (C) 2003 Clemson University
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7. /* 
  8.  * This simple visualization watches a socket for the locations of particles
  9.  * and simply displays them in a 3D world.  It allows the user to move around
  10.  * the world as well.
  11.  *
  12.  */
  13.  
  14. #include <math.h>            
  15. #include <time.h>
  16. #include <stdio.h>        
  17. #include <stdlib.h>
  18. #include <stdarg.h>
  19. #include <string.h>
  20. #include <values.h>
  21. #include <sys/types.h>
  22. #include <sys/socket.h>
  23. #include <sys/time.h>
  24. #include <netdb.h>
  25. #include <netinet/in.h>
  26. #include <unistd.h>
  27. #include <errno.h>
  28. #include <fcntl.h>
  29. #include <sys/stat.h>
  30. #include <GL/gl.h>    
  31. #include <GL/glu.h>    
  32. #include <GL/glx.h>
  33. #include <GL/glut.h>
  34. #include "SDL.h"
  35. #include "SDL_ttf.h"
  36. #include "sockio.h"
  37.  
  38. #define BOOL    int
  39. #define FALSE   0
  40. #define TRUE    1
  41.  
  42. #define FONT_SIZE 12
  43.  
  44. #define WINDOW_TITLE "glpv: OpenGL Particle Visualization"
  45.  
  46. int SCWIDTH;
  47. int SCHEIGHT;
  48.  
  49. typedef struct vector {
  50.     double x, y, z;
  51. } vector;
  52.  
  53. typedef struct body {
  54.        int id;
  55.     double mass;
  56.     vector position;
  57.     vector velocity;
  58.     vector force;
  59. } body;
  60.  
  61. typedef struct header {
  62.     int numbodies;
  63.     int cycle;
  64.     float timestep;
  65. } header;
  66.  
  67. header info_header;
  68. int numbodies = -1;
  69. int iteration = -1;
  70. float timestep = -1.0;
  71. float abtime = 0.0;
  72.  
  73. /* socket stuff */
  74. struct sockaddr_in mysin, fsin;
  75.  
  76. body *bodies;
  77.  
  78. int drawAxes = 1;
  79. int drawLines = 0;
  80. int cubes = 1;
  81. int cur = 0;
  82. int paused = 0;
  83. int drawNumbers = 0;
  84. float cube_size = 0.03;
  85. int def_colors = 0;
  86.  
  87. struct timeval start_bsps, end_bsps, start_fps, end_fps;
  88. float bsps = 0.0;
  89. float fps = 0.0;
  90. int timing_num_recvd = 0;
  91. int timing_max_recvd = 10;
  92. int fps_num = 0;
  93. int fps_num_max = 10;
  94.  
  95. int bsps_user_desired = 80;
  96. long usecs_per_bs = (long)((float)1000000/(float)1);
  97.  
  98. int checkpoint_fd = -1;
  99. int file_input = FALSE;
  100. long elapsed_usecs = 0;
  101.  
  102. int connected = 0;
  103.  
  104. int movie_number = 0;
  105. int MAKING_MOVIE = FALSE;
  106.  
  107. Uint8* keys;                    
  108. BOOL active=TRUE;        
  109. BOOL fullscreen=FALSE;    
  110.  
  111. GLfloat    xrot,yrot,zrot, xspeed,yspeed,zspeed, cx,cy,cz=-15;            
  112.  
  113. int key=1;            
  114.  
  115. SDL_Surface *screen;
  116. SDL_Rect dstrect;
  117. SDL_Surface *text;
  118.  
  119. typedef struct                
  120. {
  121.     float    x, y, z;        
  122. } VERTEX;            
  123.  
  124. VERTEX *colors;
  125.  
  126. void Quit(int retcode);
  127.  
  128. GLvoid ReSizeGLScene(GLsizei width, GLsizei height)    
  129. {
  130.     if (height==0) height=1;
  131.  
  132.     glViewport(0,0,width,height);                    
  133.  
  134.     glMatrixMode(GL_PROJECTION);                
  135.     glLoadIdentity();                            
  136.  
  137.     gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
  138.  
  139.     glMatrixMode(GL_MODELVIEW);    
  140.     glLoadIdentity();                
  141. }
  142.  
  143. GLvoid glPrint(const char *s)
  144. {
  145.     if(s && strlen(s)) {
  146.         while(*s) {
  147.             glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *s);
  148.             s++;
  149.         }
  150.     }
  151. }
  152.  
  153. void WritePPM(char *filename, unsigned char *pixels, int xdim, int ydim)
  154. {
  155.     FILE *fp;
  156.  
  157.     fp = fopen(filename, "w");
  158.     if(fp == NULL) {
  159.         fprintf(stderr, "WritePPM() cannot create the PPM file: %s\n", 
  160.           filename);
  161.         return;
  162.     }
  163.  
  164.     fprintf(fp, "P6\n%d %d\n255\n", xdim, ydim);
  165.     fwrite(pixels, sizeof(int), ydim*xdim, fp);
  166.  
  167.     fflush(fp);
  168.     fclose(fp);
  169. }
  170.  
  171. void drawCube(float x, float y, float z, float th, float cr, float cg, float cb)
  172. {
  173.     /* top */
  174.     glBegin(GL_QUADS);
  175.     glVertex3f(x-th,y-th,z-th);
  176.     glVertex3f(x+th,y-th,z-th);
  177.     glVertex3f(x+th,y-th,z+th);
  178.     glVertex3f(x-th,y-th,z+th);
  179.  
  180.     glVertex3f(x-th,y+th,z-th);
  181.     glVertex3f(x+th,y+th,z-th);
  182.     glVertex3f(x+th,y+th,z+th);
  183.     glVertex3f(x-th,y+th,z+th);
  184.  
  185.     glVertex3f(x+th,y-th,z-th);
  186.     glVertex3f(x+th,y+th,z-th);
  187.     glVertex3f(x+th,y+th,z+th);
  188.     glVertex3f(x+th,y-th,z+th);
  189.  
  190.     glVertex3f(x-th,y-th,z-th);
  191.     glVertex3f(x-th,y+th,z-th);
  192.     glVertex3f(x-th,y+th,z+th);
  193.     glVertex3f(x-th,y-th,z+th);
  194.  
  195.     glVertex3f(x-th,y-th,z-th);
  196.     glVertex3f(x+th,y-th,z-th);
  197.     glVertex3f(x+th,y+th,z-th);
  198.     glVertex3f(x-th,y+th,z-th);
  199.  
  200.     glVertex3f(x-th,y-th,z+th);
  201.     glVertex3f(x+th,y-th,z+th);
  202.     glVertex3f(x+th,y+th,z+th);
  203.     glVertex3f(x-th,y+th,z+th);
  204.     glEnd();
  205. }
  206.  
  207. void Quit(int ret) 
  208. {
  209.     SDL_Quit();
  210.     exit(ret);
  211. }
  212.  
  213. int InitGL(GLvoid)            
  214. {
  215.  
  216.     // Set The Blending Function For Translucency
  217.     glBlendFunc(GL_SRC_ALPHA,GL_ONE);    
  218.     // This Will Clear The Background Color To Black
  219.     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);        
  220.     // Enables Clearing Of The Depth Buffer
  221.     glClearDepth(1.0);    
  222.     // The Type Of Depth Test To Do
  223.     glDepthFunc(GL_LESS);    
  224.     // Enables Depth Testing
  225.     glEnable(GL_DEPTH_TEST);    
  226.     // Enables Smooth Color Shading
  227.     glShadeModel(GL_SMOOTH);    
  228.     // Really Nice Perspective Calculations
  229.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  230.  
  231.     return TRUE;                                
  232. }
  233.  
  234. void CheckSockets(int sock_connected)
  235. {
  236.     int retval, i;
  237.     fd_set readfds;
  238.     struct timeval now;
  239.  
  240.     if(connected) {
  241.         FD_ZERO(&readfds);
  242.         FD_SET(sock_connected, &readfds);
  243.         now.tv_sec = 0;
  244.         now.tv_usec = 0;
  245.         retval = select(sock_connected+1, &readfds, NULL, NULL, &now);
  246.         if(retval > 0) {
  247.         if(FD_ISSET(sock_connected, &readfds)) {
  248.             if(recv(sock_connected, &info_header, sizeof(header), 
  249.               MSG_WAITALL)!=sizeof(header)) {
  250.             }
  251.             else {
  252.             if(numbodies == -1) {
  253.                 numbodies = info_header.numbodies;
  254.                 printf("RECVD numbodies = %d\n", numbodies);
  255.                 bodies = (body*)malloc(numbodies*sizeof(body));
  256.                 colors = (VERTEX*)malloc(sizeof(VERTEX)*numbodies);
  257.                 for(i=0; i<numbodies; i++)
  258.                 colors[i].x = colors[i].y = colors[i].z = 0.0;
  259.             }
  260.             numbodies = info_header.numbodies;
  261.             iteration = info_header.cycle;
  262.             timestep = info_header.timestep;
  263.             abtime = timestep * iteration;
  264.             retval = brecv(sock_connected, bodies, 
  265.               numbodies*sizeof(body));
  266.             if(timing_num_recvd == 0) {
  267.                 gettimeofday(&start_bsps, NULL);
  268.             }
  269.             timing_num_recvd++;
  270.             if(timing_num_recvd == timing_max_recvd) {
  271.                 int elapsed_secs;
  272.                 gettimeofday(&end_bsps, NULL);
  273.                 /* calculate the seconds that have elapsed */
  274.                 elapsed_secs = end_bsps.tv_sec - start_bsps.tv_sec;
  275.                 /* if no time has passed, then lets wait twice as 
  276.                  * long and try again */
  277.                 if(elapsed_secs == 0) timing_max_recvd *= 2;
  278.                 else {
  279.                 bsps = ((float)timing_max_recvd)/
  280.                   ((float)elapsed_secs);
  281.                 if(elapsed_secs > 4) timing_max_recvd /= 2;
  282.                 timing_num_recvd = 0;
  283.                 }
  284.             }
  285.             }
  286.         }
  287.         }
  288.         return;
  289.     }
  290. }
  291.  
  292. void readFileStep(void)
  293. {
  294.     int i;
  295.  
  296.     read(checkpoint_fd, &info_header, sizeof(header));
  297.     if(numbodies == -1) {
  298.         numbodies = info_header.numbodies;
  299.         printf("numbodies = %d\n", numbodies);
  300.         bodies = (body*)malloc(numbodies*sizeof(body));
  301.         colors = (VERTEX*)malloc(sizeof(VERTEX)*numbodies);
  302.         for(i=0; i<numbodies; i++)
  303.         colors[i].x = colors[i].y = colors[i].z = 0.0;
  304.     }
  305.     numbodies = info_header.numbodies;
  306.     iteration = info_header.cycle;
  307.     timestep = info_header.timestep;
  308.     abtime = timestep * iteration;
  309.  
  310.     read(checkpoint_fd, bodies, numbodies*sizeof(body));
  311.  
  312.     return;
  313. }
  314.  
  315. void draw2DText(void)
  316. {
  317.     glColor3f(1.0f, 0.0f, 0.0f);
  318.     glDisable(GL_DEPTH_TEST); 
  319.     {
  320.         glMatrixMode(GL_PROJECTION);
  321.         glPushMatrix();
  322.         {
  323.         glLoadIdentity();
  324.         glMatrixMode(GL_MODELVIEW);
  325.         glPushMatrix();
  326.         {
  327.             int numlines = 0;
  328.             int xoffset = 5;
  329.             int yoffset = 5;
  330.             glLoadIdentity();
  331.              gluOrtho2D(0, SCWIDTH, 0, SCHEIGHT);
  332.              glRasterPos2f(xoffset, yoffset + FONT_SIZE*numlines++);
  333.             {
  334.             char str[128];
  335.             if(file_input == FALSE)
  336.                 sprintf(str, "%.0f BodysetsPS, %0.2f FPS", 
  337.                   bsps, fps);
  338.             else
  339.                 sprintf(str, "%d BodysetsPS, %0.2f FPS", 
  340.                   bsps_user_desired, fps);
  341.             glPrint(str);
  342.             } 
  343.             glRasterPos2f(xoffset, yoffset + FONT_SIZE*numlines++);
  344.             if(cubes) glPrint("Draw Mode: CUBES");
  345.             else glPrint("Draw Mode: POINTS");
  346.             if(numbodies != -1 && iteration != -1 && timestep != -1.0) {
  347.             char str[128];
  348.             sprintf(str, "Iteration: %d (T = %f, %d bodies, "
  349.               "timestep %f)",
  350.               iteration, abtime, numbodies, timestep);
  351.             glRasterPos2f(xoffset, yoffset + FONT_SIZE*numlines++);
  352.             glPrint(str);
  353.             }
  354.             if(paused) {
  355.             glRasterPos2f(xoffset, yoffset + FONT_SIZE*numlines++);
  356.             glPrint("[ PAUSED ]");
  357.             }
  358.         }
  359.         glPopMatrix();
  360.         }
  361.         glMatrixMode(GL_PROJECTION);
  362.         glPopMatrix();
  363.     }
  364.     glMatrixMode(GL_MODELVIEW);
  365. }
  366.  
  367. int DrawGLScene(int sock_accept, int *sock_connected)
  368. {
  369.     int i, j;
  370.     fd_set readfds;
  371.     struct timeval now;
  372.     int retval, fromlen;
  373.     float f1, f2, f3;
  374.     char str[32];
  375.  
  376.     if(fps_num == 0) gettimeofday(&start_fps, NULL);
  377.     fps_num++;
  378.  
  379.     if(file_input == FALSE) {
  380.         FD_ZERO(&readfds);
  381.         FD_SET(sock_accept, &readfds);
  382.         now.tv_sec = 0;
  383.         now.tv_usec = 0;
  384.         retval = select(sock_accept+1, &readfds, NULL, NULL, &now);
  385.         if(retval > 0) {
  386.         if(FD_ISSET(sock_accept, &readfds)) {
  387.               if((*sock_connected=accept(sock_accept,(struct 
  388.               sockaddr*)&fsin, &fromlen))!=-1) {
  389.             printf("[Connection established]\n");
  390.             connected = TRUE;
  391.             }
  392.             else {
  393.             perror("accept");
  394.             exit(1);
  395.             }
  396.         }
  397.         }
  398.         if(connected && !paused) CheckSockets(*sock_connected);
  399.     }
  400.     else if(file_input == TRUE) {
  401.         if(!paused) {
  402.         if(timing_num_recvd == 0) {
  403.             gettimeofday(&start_bsps, NULL);
  404.         }
  405.         gettimeofday(&end_bsps, NULL);
  406.         /* calculate the seconds that have elapsed */
  407.         elapsed_usecs = 1000000*(end_bsps.tv_sec - start_bsps.tv_sec) 
  408.           + (end_bsps.tv_usec - start_bsps.tv_usec);
  409.         if(timing_num_recvd < bsps_user_desired) {
  410.             if(elapsed_usecs > (timing_num_recvd * usecs_per_bs)) {
  411.             readFileStep();
  412.             timing_num_recvd++;
  413.             }
  414.         }
  415.         else {
  416.             if(elapsed_usecs > 1000000) {
  417.             timing_num_recvd = 0;
  418.             elapsed_usecs = 0;
  419.             }
  420.         }
  421.         }
  422.     }
  423.  
  424.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  425.     glLoadIdentity();                                
  426.     /* if you want to follow a body run this */
  427.     /* well - this may work :) */
  428. #if 0
  429.     gluLookAt(
  430.         bodies_obj.points[1].x + 1,
  431.         bodies_obj.points[1].y + 1,
  432.         bodies_obj.points[1].z + 1,
  433.         bodies_obj.points[1].x + bodies_obj.points[1].y,
  434.         bodies_obj.points[1].y + bodies_obj.points[1].y,
  435.         bodies_obj.points[1].z + bodies_obj.points[1].z,
  436.         0.0f, 1.0f, 0.0f);
  437.         TURN OFF XLATE THOUGH 
  438. #endif
  439.     glTranslatef(cx,cy,cz);    // Xlate The The Current Pos To Start Drawing
  440.     glRotatef(xrot,1,0,0);    // Rotate On The X Axis By xrot
  441.     glRotatef(yrot,0,1,0);    // Rotate On The Y Axis By yrot
  442.     glRotatef(zrot,0,0,1);    // Rotate On The Z Axis By zrot
  443.  
  444.     // Increase xrot,yrot & zrot by xspeed, yspeed & zspeed
  445.     xrot+=xspeed; yrot+=yspeed; zrot+=zspeed;    
  446.  
  447.     if(numbodies > 0) {
  448.         if(!cubes) glBegin(GL_POINTS);
  449.         for(i=0; i<numbodies; i++) {
  450.         if(colors[i].x == 0.0 && 
  451.           colors[i].y == 0.0 && 
  452.           colors[i].z == 0.0) {
  453.             if(bodies[i].mass <= 5.0) { 
  454.                    f1 = 1.0; f2 = 1.0; f3 = 1.0; 
  455.             }
  456.             else if(bodies[i].mass <= 10.0) { 
  457.                 f1 = 1.0; f2 = 0.0; f3 = 0.0; 
  458.             }
  459.             else if(bodies[i].mass <= 50.0) { 
  460.                    f1 = 0.0; f2 = 1.0; f3 = 1.0; 
  461.             }
  462.             else if(bodies[i].mass <= 100.0) { 
  463.                    f1 = 0.0; f2 = 1.0; f3 = 0.0; 
  464.             }
  465.             else { 
  466.                    f1 = 1.0; f2 = 1.0; f3 = 1.0; 
  467.             }
  468.             colors[i].x = f1;
  469.             colors[i].y = f2;
  470.             colors[i].z = f3;
  471.         }
  472.         glColor3f(colors[i].x, colors[i].y, colors[i].z);
  473.         if(cubes == 1) { 
  474.             drawCube(bodies[i].position.x, bodies[i].position.y, 
  475.               bodies[i].position.z, cube_size, colors[i].x, 
  476.               colors[i].y, colors[i].z);
  477.             if(drawNumbers) {
  478.             glColor3f(0.0f, 0.0f, 1.0f);
  479.             glRasterPos3f(bodies[i].position.x, 
  480.               bodies[i].position.y, bodies[i].position.z);
  481.             sprintf(str,"%3.3f", bodies[i].mass);
  482.             glPrint(str);
  483.             }
  484.         }
  485.         else { /* points */
  486.             glVertex3f(bodies[i].position.x,
  487.               bodies[i].position.y,
  488.               bodies[i].position.z);
  489.         }
  490.         }
  491.         glEnd();
  492.         if(drawLines == 1) {
  493.         glEnable(GL_LINE_SMOOTH);
  494.         glColor3f(0.0f, 1.0f, 0.0f);
  495.         glBegin(GL_LINES);
  496.         for(i=0; i<numbodies; i++) {
  497.             glVertex3d(bodies[i].position.x,
  498.               bodies[i].position.y,
  499.               bodies[i].position.z);
  500.             glVertex3d(bodies[(i+1)%numbodies].position.x,
  501.               bodies[(i+1)%numbodies].position.y,
  502.               bodies[(i+1)%numbodies].position.z);
  503.         }
  504.         glEnd();
  505.         glDisable(GL_LINE_SMOOTH);
  506.         }
  507.         else if(drawLines == 2) {
  508.         glEnable(GL_LINE_SMOOTH);
  509.         glColor3f(0.0f, 1.0f, 0.0f);
  510.         glBegin(GL_LINES);
  511.         glVertex3d(bodies[cur].position.x,
  512.           bodies[cur].position.y,
  513.           bodies[cur].position.z);
  514.         glVertex3d(bodies[(cur+1)%numbodies].position.x,
  515.           bodies[(cur+1)%numbodies].position.y,
  516.           bodies[(cur+1)%numbodies].position.z);
  517.         cur = (cur+1)%numbodies;
  518.         glEnd();
  519.         glDisable(GL_LINE_SMOOTH);
  520.         }
  521.         else if(drawLines == 3) {
  522.         glEnable(GL_LINE_SMOOTH);
  523.         glColor3f(0.0f, 1.0f, 0.0f);
  524.         glBegin(GL_LINES);
  525.         for(i=0; i<numbodies; i++) {
  526.             int curelement = i;
  527.             float mind = MAXFLOAT;
  528.             for(j=0; j<numbodies; j++) {
  529.             if(i != j) { /* don't compare w/ myself */
  530.                 float curd = ((bodies[i].position.x - 
  531.                   bodies[j].position.x)*(bodies[i].position.x - 
  532.                   bodies[j].position.x)) + 
  533.                   ((bodies[i].position.y - bodies[j].position.y)*
  534.                   (bodies[i].position.y - bodies[j].position.y)) +
  535.                   ((bodies[i].position.z - bodies[j].position.z)*
  536.                   (bodies[i].position.z - bodies[j].position.z));
  537.                 if(curd < mind) {
  538.                 mind = curd;
  539.                 curelement = j;
  540.                 }
  541.             }
  542.             }
  543.             glVertex3d(bodies[i].position.x,
  544.               bodies[i].position.y,
  545.               bodies[i].position.z);
  546.             glVertex3d(bodies[curelement].position.x,
  547.               bodies[curelement].position.y,
  548.               bodies[curelement].position.z);
  549.         }
  550.         glEnd();
  551.         glDisable(GL_LINE_SMOOTH);
  552.         }
  553.         else if(drawLines == 4) {
  554.         glEnable(GL_LINE_SMOOTH);
  555.         glColor3f(0.0f, 1.0f, 0.0f);
  556.         glBegin(GL_LINES);
  557.         for(i=0; i<numbodies; i++) {
  558.             for(j=0; j<numbodies; j++) {
  559.             glVertex3d(bodies[i].position.x,
  560.               bodies[i].position.y,
  561.               bodies[i].position.z);
  562.             glVertex3d(bodies[j].position.x,
  563.               bodies[j].position.y,
  564.               bodies[j].position.z);
  565.             }
  566.         }
  567.         glEnd();
  568.         glDisable(GL_LINE_SMOOTH);
  569.         }
  570.         // Done Drawing Points
  571.     }
  572.  
  573.     if(drawAxes) {
  574.         /* SMOOTH lines look good but are hardware intense */
  575.         //glEnable(GL_LINE_SMOOTH);
  576.         glLineWidth(0.5f);
  577.         glColor3f(0.7f, 0.7f, 0.7f);
  578.  
  579.         glEnable(GL_LINE_STIPPLE);
  580.         // Set the stippling pattern
  581.         glLineStipple(3, 0xAAAA);
  582.         //glLineStipple(2, 0x0C0F);
  583.         glBegin(GL_LINES);
  584.         glVertex3d(-30,0,0);
  585.         glVertex3d(30,0,0);
  586.         
  587.         glVertex3d(0,-30,0);
  588.         glVertex3d(0,30,0);
  589.         
  590.         glVertex3d(0,0,-30);
  591.         glVertex3d(0,0,30);
  592.         glEnd();
  593.         //glDisable(GL_LINE_SMOOTH);
  594.         glDisable(GL_LINE_STIPPLE);
  595.         
  596.         glColor3f(0.0f, 1.0f, 0.0f);
  597.         glRasterPos3f(-10.5,0,0);
  598.         glPrint("-X");
  599.         glRasterPos3f(10.1,0,0);
  600.         glPrint("+X");
  601.         glRasterPos3f(0,-10.5,0);
  602.         glPrint("-Y");
  603.         glRasterPos3f(0,10.1,0);
  604.         glPrint("+Y");
  605.         glRasterPos3f(0,0,-10.5);
  606.         glPrint("-Z");
  607.         glRasterPos3f(0,0,10.1);
  608.         glPrint("+Z");
  609.     }
  610.     draw2DText();
  611.  
  612.     if(fps_num == fps_num_max) {
  613.         int elapsed_secs;
  614.         gettimeofday(&end_fps, NULL); 
  615.         /* calculate the seconds that have elapsed */
  616.         elapsed_secs = end_fps.tv_sec - start_fps.tv_sec;
  617.         /* if no time has passed, then lets wait twice as long and 
  618.          * try again */
  619.         if(elapsed_secs == 0 && fps_num_max < 100) fps_num_max *= 2;
  620.         else {
  621.         if(elapsed_secs == 0) elapsed_secs = 1;
  622.         fps = ((float)fps_num_max)/((float)elapsed_secs);
  623.         if(elapsed_secs > 4) fps_num_max /= 2;
  624.         fps_num = 0;
  625.         }
  626.     }
  627.  
  628.     if(MAKING_MOVIE && ((iteration != movie_number) || paused)) {
  629.         unsigned char *pixels, *fn;
  630.  
  631.         pixels = (unsigned char*)malloc(3*SCWIDTH*SCHEIGHT*
  632.           sizeof(unsigned char));
  633.         fn = (unsigned char*)malloc(80);
  634.  
  635.         glReadBuffer(GL_FRONT);
  636.         glReadPixels(0,0,SCWIDTH,SCHEIGHT,GL_RGB,GL_UNSIGNED_BYTE,pixels);
  637.     
  638.         sprintf(fn, "/tmp/sshot-%05d.ppm", movie_number);
  639.          WritePPM(fn, pixels, SCWIDTH, SCHEIGHT);
  640.         
  641.         free(pixels);
  642.         free(fn);
  643.  
  644.         movie_number++;
  645.     }
  646.  
  647.     return TRUE;
  648. }
  649.  
  650.  
  651. /* This Code Creates Our OpenGL Window.  Parameters Are:        
  652.  *    title        - Title To Appear At The Top Of The Window
  653.  *    width        - Width Of The GL Window Or Fullscreen Mode
  654.  *    height        - Height Of The GL Window Or Fullscreen Mode
  655.  *    bits        - Number Of Bits To Use For Color (8/16/24/32)
  656.  *    fullscreenflag    - Use Fullscreen Mode (TRUE) Or Windowed 
  657.  *              Mode (FALSE)
  658.  */
  659. BOOL CreateGLWindow(char* title, int width, int height, int bits, 
  660.   BOOL fullscreenflag)
  661. {
  662.     Uint32 flags;
  663.  
  664.     fullscreen=fullscreenflag; // Set The Global Fullscreen Flag
  665.     flags = SDL_OPENGL;
  666.     if(fullscreenflag) {
  667.         flags |= SDL_FULLSCREEN;
  668.     }
  669.     if((screen = SDL_SetVideoMode(width, height, 0, flags)) == NULL) {
  670.         return FALSE;
  671.     }
  672.     SDL_WM_SetCaption(title, WINDOW_TITLE);
  673.  
  674.     // Set Up Our Perspective GL Screen
  675.     ReSizeGLScene(width, height);                            
  676.     // Initialize Our Newly Created GL Window
  677.     if(!InitGL()) {
  678.         Quit(1);    // Reset The Display
  679.         return FALSE;    // Return FALSE
  680.     }
  681.  
  682.     return TRUE;        // Success
  683. }
  684.  
  685. int TOGGLE(int x) 
  686. {
  687.     if(x == 1) return 0;
  688.     else return 1;
  689. }
  690.  
  691. int main(int argc, char *argv[])
  692. {
  693.     BOOL    done=FALSE;
  694.     int sock_accept = -1, sock_connected;
  695.     float zoomz = 0.06;
  696.     float fx = 0, fy = 0, fz = 0;
  697.     int i;
  698.     
  699.     if(argc != 4) {
  700.         fprintf(stderr,"Syntax: %s <screen width> <screen height> "
  701.           "<port to bind to OR checkpoint file to read from>\n", 
  702.           argv[0]);
  703.         exit(1);
  704.     }
  705.     SCWIDTH = atoi(argv[1]);
  706.     SCHEIGHT = atoi(argv[2]);
  707.  
  708.     srand((unsigned int)time(NULL));
  709.  
  710.  
  711.     if(atoi(argv[3]) == 0) {
  712.         checkpoint_fd = open(argv[3], O_RDONLY);
  713.         if(checkpoint_fd == -1) {
  714.         perror("open");
  715.         exit(1);
  716.         }
  717.         file_input = TRUE;
  718.     }
  719.     
  720.     else {
  721.         sock_accept = new_sock();
  722.         printf("Binding to port: %d\n", atoi(argv[3]));
  723.         bind_sock(sock_accept, atoi(argv[3]));
  724.         if(listen(sock_accept,5)<0) {
  725.         perror("listen");
  726.         exit(1);
  727.         }
  728.     }
  729.  
  730.     /* Initialize SDL */
  731.     if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
  732.         fprintf(stderr, "Couldn't init SDL: %s\n", SDL_GetError());
  733.         return 1;
  734.     }
  735.  
  736.     // Create Our OpenGL Window
  737.     if (!CreateGLWindow(WINDOW_TITLE,SCWIDTH,SCHEIGHT,
  738.         16,fullscreen))
  739.     {
  740.         SDL_Quit();
  741.         return 0;                                    
  742.     }
  743.  
  744.     printf("COMMANDS:\n");
  745.     printf("F1 - toggle full-screen mode\n");
  746.     printf("ESC - quit\n");
  747.     printf("p - TOGGLE pause\n");
  748.     printf("m - TOGGLE movie making (look for screenshots in /tmp)\n");
  749.     printf("\n");
  750.     printf("3D Commands:\n");
  751.     printf("\tPGUP/PGDWN - rotate Z axis\n");
  752.     printf("\tKEYPAD LEFT/RIGHT - rotate X axis\n");
  753.     printf("\tKEYPAD UP/DOWN - rotate Y axis\n");
  754.     printf("\tLEFT SHIFT + any of the above rotations - put spin on "
  755.       "that axis\n");
  756.     printf("\tw/s - zoom in / out\n");
  757.     printf("\ta/d - move view field left / right\n");
  758.     printf("\tq/z - move view field up / down\n");
  759.     printf("\tk - return to original view\n");
  760.     printf("\tx - stop all axial spins\n");
  761.     printf("\n");
  762.     printf("Additional Commands:\n");
  763.     printf("\tj - TOGGLE drawing body numbers\n");
  764.     printf("\tc - switch base color drawing\n");
  765.     printf("\tv - TOGGLE drawing axes\n");
  766.     printf("\tb - TOGGLE drawing points or cubes\n");
  767.     printf("\t1 - turn off crazy line drawing\n");
  768.     printf("\t2 - draw lines between subsequent bodies\n");
  769.     printf("\t3 - draw lines between bodies, one line per iteration\n");
  770.     printf("\t4 - draw lines between closest neighbors\n");
  771.     printf("\t5 - draw lines between all bodies\n");
  772.     printf("\t-/= - modify cube size\n");
  773.     if(file_input == TRUE) {
  774.         printf("[/] - modify number of datasets read from file per "
  775.           "second\n");
  776.     }
  777.  
  778.     /* initial view of the world */
  779.     xrot = 13.0;
  780.     yrot = 28.5;
  781.     zrot = 0.0;
  782.     cz = -37.619991;
  783.     
  784.     while(!done)
  785.     {
  786.         SDL_Event event;
  787.         while ( SDL_PollEvent(&event) ) {
  788.         switch (event.type) {
  789.             case SDL_QUIT:
  790.                 done=TRUE;                
  791.                 break;
  792.             case SDL_KEYDOWN:
  793.                 switch(event.key.keysym.sym) {
  794.                     case SDLK_b: 
  795.                     cubes = cubes ? 0 : 1;
  796.                     break;
  797.                     case SDLK_v:
  798.                     drawAxes = drawAxes ? 0 : 1;
  799.                     break;
  800.                     case SDLK_m:
  801.                     MAKING_MOVIE = MAKING_MOVIE ? 0 : 1;
  802.                     if(MAKING_MOVIE)
  803.                             printf("Now making movie, look for "
  804.                       "screens in /tmp\n");
  805.                     else
  806.                             printf("Movie making turned off.\n");
  807.                     break;
  808.                     case SDLK_c:
  809.                     def_colors = (def_colors + 1) % 10;
  810.                     switch(def_colors) {
  811.                             case 0:
  812.                         fx = 0.0; fy = 1.0; fz = 0.0;
  813.                         break;
  814.                             case 1:
  815.                         fx = 0.0; fy = 0.0; fz = 1.0;
  816.                         break;
  817.                             case 2:
  818.                        fx = 1.0; fy = 0.0; fz = 0.0;
  819.                         break;
  820.                             case 3:
  821.                         fx = 1.0; fy = 0.0; fz = 1.0;
  822.                         break;
  823.                             case 4:
  824.                         fx = 0.0; fy = 1.0; fz = 1.0;
  825.                         break;
  826.                             case 5:
  827.                         fx = 1.0; fy = 0.5; fz = 0.3;
  828.                         break;
  829.                             case 6:
  830.                         fx = 0.3; fy = 1.0; fz = 0.5;
  831.                         break;
  832.                             case 7:
  833.                         fx = 0.5; fy = 0.3; fz = 1.0;
  834.                        break;
  835.                             case 8:
  836.                         fx = 1.0; fy = 1.0; fz = 1.0;
  837.                         break;
  838.                             case 9:
  839.                         fx = 1.0; fy = 1.0; fz = 0.0;
  840.                         break;
  841.                     }
  842.                     for(i=0; i<numbodies; i++) {
  843.                             colors[i].x = fx;
  844.                             colors[i].y = fy;
  845.                             colors[i].z = fz;
  846.                     }
  847.                     break;
  848.                     case SDLK_p:
  849.                     paused = paused ? 0 : 1;
  850.                     break;
  851.                     case SDLK_1:
  852.                     drawLines = 0;
  853.                     break;
  854.                     case SDLK_2:
  855.                     drawLines = 1;
  856.                     break;
  857.                     case SDLK_3:
  858.                     drawLines = 2;
  859.                     break;
  860.                     case SDLK_4:
  861.                     drawLines = 3;
  862.                     break;
  863.                     case SDLK_5:
  864.                     drawLines = 4;
  865.                     break;
  866.                     case SDLK_j:
  867.                     drawNumbers = drawNumbers ? 0 : 1;
  868.                     break;
  869.                     case SDLK_k:
  870.                     xrot = 13.0;
  871.                     yrot = 28.5;
  872.                     zrot = 0.0;
  873.                     cz = -37.619991;
  874.                     break;
  875.                     case SDLK_LEFTBRACKET: 
  876.                     if(file_input == TRUE) {
  877.                             bsps_user_desired--;
  878.                             if(bsps_user_desired < 1) 
  879.                         bsps_user_desired = 1;
  880.                             usecs_per_bs = (long)((float)1000000/
  881.                             (float)bsps_user_desired);
  882.                     }
  883.                     break;
  884.                     case SDLK_RIGHTBRACKET:
  885.                     if(file_input == TRUE) {
  886.                             bsps_user_desired++;
  887.                             usecs_per_bs = (long)((float)1000000/
  888.                             (float)bsps_user_desired);
  889.                     }
  890.                     break;
  891.                     default: break;
  892.             }
  893.             default: break;
  894.         }
  895.         }
  896.         keys = SDL_GetKeyState(NULL);
  897.         // Draw The Scene.  Watch For ESC Key And Quit Messages 
  898.         // From DrawGLScene()
  899.         if ((active && !DrawGLScene(sock_accept, &sock_connected)) || 
  900.           keys[SDLK_ESCAPE])
  901.         {
  902.         done=TRUE;                    
  903.         }
  904.         else                            
  905.         {
  906.         SDL_GL_SwapBuffers();    // Swap Buffers (Double Buffering)
  907.         }
  908.  
  909.         if(keys[SDLK_PAGEUP]) {
  910.         if(keys[SDLK_LSHIFT]) zspeed += 0.01f;
  911.         else zrot += 0.5f;
  912.         }
  913.         if(keys[SDLK_PAGEDOWN]) {
  914.         if(keys[SDLK_LSHIFT]) zspeed -= 0.01f;
  915.         else zrot -= 0.5f;
  916.         }
  917.         if(keys[SDLK_DOWN]) {
  918.         if(keys[SDLK_LSHIFT]) xspeed += 0.01f;
  919.         else xrot += 0.5f;
  920.         }
  921.         if(keys[SDLK_UP]) {
  922.         if(keys[SDLK_LSHIFT]) xspeed -= 0.01f;
  923.         else xrot -= 0.5f;
  924.         }
  925.         if(keys[SDLK_RIGHT]) {
  926.         if(keys[SDLK_LSHIFT]) yspeed += 0.01f;
  927.         else yrot += 0.5f;
  928.         }
  929.         if(keys[SDLK_LEFT]) {
  930.         if(keys[SDLK_LSHIFT]) yspeed -= 0.01f;
  931.         else yrot -= 0.5f;
  932.         }
  933.  
  934.         /* stop the spinning */
  935.         if(keys[SDLK_x]) xspeed = yspeed = zspeed = 0.0f;
  936.  
  937.         if(keys[SDLK_EQUALS]) cube_size += 0.0005;
  938.         if(keys[SDLK_MINUS]) cube_size -= 0.0005;
  939.  
  940.         // Move Object Away From Viewer
  941.         if (keys[SDLK_s]) cz -= zoomz;
  942.  
  943.         // Move Object Towards Viewer
  944.         if (keys[SDLK_w]) cz+=zoomz;
  945.  
  946.         // Move Object Up
  947.         if (keys[SDLK_z]) cy+=0.01f;                
  948.  
  949.         // Move Object Down
  950.         if (keys[SDLK_q]) cy-=0.01f;                
  951.  
  952.         // Move Object Right
  953.         if (keys[SDLK_a]) cx+=0.01f;                
  954.  
  955.         // Move Object Left
  956.         if (keys[SDLK_d]) cx-=0.01f;                                        
  957.  
  958.         if (keys[SDLK_F1]) {
  959.         fullscreen=!fullscreen;    // Fullscreen / Windowed Mode
  960.         // Recreate Our OpenGL Window
  961.         if(!CreateGLWindow(WINDOW_TITLE,SCWIDTH,
  962.           SCHEIGHT,16,fullscreen))
  963.         {
  964.             done=TRUE;    // Quit If Window Was Not Created
  965.         }
  966.         }
  967.     }
  968.  
  969.     // Shutdown
  970.     close(sock_connected);
  971.     close(sock_accept);
  972.     Quit(0); // Kill The Window
  973.     SDL_Quit();
  974.     return 0;                            
  975. }
  976.