rendered paste body#include <GL/glut.h>#include <stdlib.h>#include <stdio.h>#include <math.h>#include "color_helper.h"#define USERS 28#define MAX(x,y) ((x)<(y)?(y):(x))#define MIN(x,y) ((x)>(y)?(y):(x))#define NORMAL(d,dmin,dmax) ((d)-(dmin))/((dmax)-(dmin))void glut_setup(void) ;void gl_setup(void) ;void my_setup(void);void my_display(void) ;void my_idle(void) ;void my_TimeOut(int) ;void my_keyboard( unsigned char, int , int);int theta_x;int theta_y;int ordered[USERS] = {6, 15, 8, 17, 24, 12, 2, 13, 0, 26, 7, 16, 22, 21, 23, 27, 4, 9, 18, 11, 25, 19, 1, 14, 10, 3, 5, 20};typedef struct { double video[7]; double image[7]; double ability;} User;User users[USERS];User average;User stddev;User max;User min;enum CategoryName { MENTAL_DEMAND, PHYSICAL_DEMAND, TEMPORAL_DEMAND, PERFORMANCE, EFFORT, FRUSTRATION, TOTAL_WORKLOAD};char *category_names[] = { "Mental Demand", "Physical Demand", "Temporal Demand", "Performance", "Effort", "Frustration", "Total Workload"};int main(int argc, char **argv) { /* General initialization for GLUT and OpenGL Must be called first */ glutInit( &argc, argv ) ; /* we define these setup procedures */ glut_setup() ; gl_setup() ; my_setup(); /* go into the main event loop */ glutMainLoop() ; return(0) ;}void glut_setup(void) { /* specify display mode -- here we ask for a double buffer and RGB coloring */ /* NEW: tell display we care about depth now */ glutInitDisplayMode (GLUT_DOUBLE |GLUT_RGB |GLUT_DEPTH); /* make a 400x400 window with the title of "Stitcher" placed at the top left corner */ glutInitWindowSize(1000,1000); glutInitWindowPosition(0,0); glutCreateWindow("Proj3"); /*initialize callback functions */ glutDisplayFunc( my_display ); glutKeyboardFunc(my_keyboard); /*just for fun, uncomment the line below and observe the effect :-) Do you understand now why you shd use timer events, and stay away from the idle event? */ // glutIdleFunc( my_idle ); glutTimerFunc( 20000, my_TimeOut, 0);/* schedule a my_TimeOut call with the ID 0 in 20 seconds from now */ return ;}void gl_setup(void) { /* specifies a background color: black in this case */ glClearColor(1,1,1,0) ; /* NEW: now we have to enable depth handling (z-buffer) */ glEnable(GL_DEPTH_TEST); /* NEW: setup for 3d projection */ glMatrixMode (GL_PROJECTION); glLoadIdentity(); // perspective view gluPerspective( 20.0, 1.0, 1.0, 1200.0); return;}void my_setup(void) { int count, i, j, k; theta_x = 0; theta_y = 0; double data[][USERS] = { {50, 60, 65, 55, 65, 45, 57.3333, 50, 40, 50, 55, 40, 30, 47, 27.25}, {65, 5, 65, 100, 100, 100, 93, 30, 5, 5, 80, 75, 75, 57.3333, 10.3333}, {80, 80, 75, 20, 85, 80, 64.3333, 80, 75, 70, 25, 80, 65, 60.6667, 29.3333}, {80, 45, 35, 65, 75, 80, 72, 55, 35, 85, 50, 75, 60, 65, 8.8333}, {75, 60, 60, 65, 65, 60, 67.3333, 70, 70, 65, 65, 70, 75, 69.6667, 18.3333}, {50, 50, 55, 50, 50, 50, 51, 55, 55, 55, 50, 55, 30, 53.6667, 8.6667}, {50, 55, 70, 40, 70, 65, 58.3333, 50, 40, 65, 20, 45, 55, 46.3333, 68.77}, {90, 10, 80, 80, 60, 60, 76.6667, 90, 10, 80, 80, 80, 65, 81.3333, 25.6667}, {40, 10, 60, 30, 45, 25, 37.6667, 35, 20, 30, 30, 45, 30, 35.6667, 47.6667}, {80, 80, 75, 45, 85, 60, 68, 25, 45, 35, 75, 35, 25, 49.6667, 17.8333}, {70, 25, 65, 70, 80, 65, 71.6667, 80, 20, 65, 90, 85, 80, 82.3333, 9.4167}, {65, 45, 40, 70, 75, 65, 60.3333, 35, 35, 40, 20, 25, 25, 30, 14}, {65, 10, 80, 35, 70, 75, 60.3333, 40, 10, 65, 45, 20, 30, 45.6667, 30.6667}, {85, 70, 100, 60, 90, 55, 74.6667, 65, 30, 35, 25, 85, 80, 49.6667, 28.92}, {50, 55, 100, 55, 70, 50, 68.3333, 65, 50, 60, 55, 75, 40, 64.3333, 9.6667}, {70, 40, 70, 40, 65, 70, 61.6667, 65, 40, 70, 35, 70, 50, 58, 49.5833}, {65, 90, 70, 30, 75, 65, 68, 80, 90, 65, 50, 75, 95, 83.3333, 24.6667}, {95, 40, 75, 80, 80, 45, 82, 80, 20, 65, 50, 100, 40, 70.6667, 47}, {100, 65, 100, 15, 100, 65, 87.3333, 55, 55, 55, 70, 20, 20, 53, 16}, {80, 80, 95, 30, 95, 95, 87.6667, 90, 85, 75, 25, 75, 80, 67, 11.6667}, {40, 40, 75, 35, 85, 70, 66.6667, 60, 60, 60, 70, 75, 45, 65, 7.4167}, {65, 15, 15, 30, 55, 30, 42.3333, 65, 25, 35, 55, 65, 80, 61.6667, 21.6667}, {40, 25, 45, 15, 80, 10, 45.3333, 35, 20, 50, 20, 85, 20, 45, 22.5833}, {65, 55, 65, 75, 65, 55, 67, 85, 65, 65, 65, 45, 70, 71.6667, 20.6667}, {75, 15, 35, 55, 60, 40, 59.3333, 80, 15, 55, 65, 75, 35, 68.6667, 45.0833}, {40, 65, 30, 80, 60, 65, 51.6667, 30, 55, 25, 70, 50, 55, 43, 12.5}, {90, 25, 60, 70, 70, 85, 78, 85, 15, 30, 85, 60, 85, 74.6667, 26.26}, {75, 65, 65, 55, 75, 55, 65, 80, 70, 55, 45, 75, 55, 67.6667, 19.25} }; i = 7; while (i--) { average.video[i] = 0.0; average.image[i] = 0.0; stddev.image[i] = 0.0; stddev.video[i] = 0.0; max.video[i] = 0.0; max.image[i] = 0.0; min.video[i] = 100.0; min.image[i] = 100.0; } average.ability = 0.0; stddev.ability = 0.0; max.ability = 0.0; min.ability = 100.0; i = USERS; while (i--) { j = 7; while (j--) { users[i].video[j] = data[i][j]; users[i].image[j] = data[i][j+7]; average.video[j] += data[i][j]; average.image[j] += data[i][j+7]; max.video[j] = MAX(max.video[j], data[i][j]); max.image[j] = MAX(max.image[j], data[i][j+7]); min.video[j] = MIN(min.video[j], data[i][j]); min.image[j] = MIN(min.image[j], data[i][j+7]); } users[i].ability = data[i][14]; average.ability += data[i][14]; max.ability = MAX(max.ability, data[i][14]); min.ability = MIN(min.ability, data[i][14]); } i = 7; while (i--) { average.image[i] /= (double)USERS; average.video[i] /= (double)USERS; } average.ability /= (double)USERS; i = USERS; while (i--) { j = 7; while (j--) { stddev.video[j] += pow(users[i].video[j]-average.video[j], 2.0); stddev.image[j] += pow(users[i].image[j]-average.image[j], 2.0); } stddev.ability += pow(users[i].ability-average.ability, 2.0); } i = 7; while (i--) { stddev.video[i] = sqrt(stddev.video[i]/(double)USERS); stddev.image[i] = sqrt(stddev.image[i]/(double)USERS); } stddev.ability = sqrt(stddev.ability/(double)USERS); return;}void draw_background() { int i, j; HSVAColor hsva = {BLUE, 1.0, 1.0, 0.2}; RGBAColor rgba; char output[4]; glColor3f(0.2,0.2,0.2); for (i=0.0; i<100.1; i+=20.0) { sprintf(output,"%d",(int)i); glRasterPos3f(-15.0, i, 5.0); for (j=0; j<3; j++) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, output[j]); } glBegin(GL_LINE_STRIP); glVertex3f(-10.0, i, 5.0); glVertex3f(-5.0, i, 5.0); glEnd(); } // Image hsva.s = NORMAL((average.ability+min.ability)/2.0,min.ability,max.ability)/2.0; rgba = hsva_to_rgba(hsva); glColor4f(rgba.r, rgba.g, rgba.b, rgba.a); i = 6; while (i--) { glBegin(GL_POLYGON); glVertex3f(50.0*i + 1.0, min.image[i], 0.0); glVertex3f(50.0*i + 1.0, (average.image[i]+min.image[i])/2.0, 0.0); glVertex3f(50.0*(i+1) - 1.0, (average.image[i+1]+min.image[i+1])/2.0, 0.0); glVertex3f(50.0*(i+1) - 1.0, min.image[i+1], 0.0); glEnd(); glBegin(GL_POLYGON); glVertex3f(50.0*i + 1.0, max.image[i], 0.0); glVertex3f(50.0*i + 1.0, (average.image[i]+max.image[i])/2.0, 0.0); glVertex3f(50.0*(i+1) - 1.0, (average.image[i+1]+max.image[i+1])/2.0, 0.0); glVertex3f(50.0*(i+1) - 1.0, max.image[i+1], 0.0); glEnd(); } hsva.s = NORMAL((average.ability+max.ability)/2.0,min.ability,max.ability)/2.0; rgba = hsva_to_rgba(hsva); glColor4f(rgba.r, rgba.g, rgba.b, rgba.a); i = 6; while (i--) { glBegin(GL_POLYGON); glVertex3f(50.0*i + 1.0, (average.image[i]+min.image[i])/2.0, 0.0); glVertex3f(50.0*i + 1.0, average.image[i] - 0.5, 0.0); glVertex3f(50.0*(i+1) - 1.0, average.image[i+1] - 0.5, 0.0); glVertex3f(50.0*(i+1) - 1.0, (average.image[i+1]+min.image[i+1])/2.0, 0.0); glEnd(); glBegin(GL_POLYGON); glVertex3f(50.0*i + 1.0, (average.image[i]+max.image[i])/2.0, 0.0); glVertex3f(50.0*i + 1.0, average.image[i] + 0.5, 0.0); glVertex3f(50.0*(i+1) - 1.0, average.image[i+1] + 0.5, 0.0); glVertex3f(50.0*(i+1) - 1.0, (average.image[i+1]+max.image[i+1])/2.0, 0.0); glEnd(); } i = USERS; while (i--) { hsva.s = NORMAL(users[ordered[i]].ability,min.ability,max.ability)*0.7+0.3; rgba = hsva_to_rgba(hsva); glColor4f(rgba.r, rgba.g, rgba.b, rgba.a); j = 7; while (j--) { glTranslatef(50.0*j, users[ordered[i]].image[j], 0.0); glutSolidSphere(1.0, 4, 4); glTranslatef(-50.0*j, -users[ordered[i]].image[j], 0.0); } } // Video hsva.h = GREEN; hsva.s = NORMAL((average.ability+min.ability)/2.0,min.ability,max.ability)/2.0; rgba = hsva_to_rgba(hsva); glColor4f(rgba.r, rgba.g, rgba.b, rgba.a); i = 6; while (i--) { glBegin(GL_POLYGON); glVertex3f(50.0*i + 1.0, min.video[i], 20.0); glVertex3f(50.0*i + 1.0, (average.video[i]+min.video[i])/2.0, 20.0); glVertex3f(50.0*(i+1) - 1.0, (average.video[i+1]+min.video[i+1])/2.0, 20.0); glVertex3f(50.0*(i+1) - 1.0, min.video[i+1], 20.0); glEnd(); glBegin(GL_POLYGON); glVertex3f(50.0*i + 1.0, max.video[i], 20.0); glVertex3f(50.0*i + 1.0, (average.video[i]+max.video[i])/2.0, 20.0); glVertex3f(50.0*(i+1) - 1.0, (average.video[i+1]+max.video[i+1])/2.0, 20.0); glVertex3f(50.0*(i+1) - 1.0, max.video[i+1], 20.0); glEnd(); } hsva.s = NORMAL((average.ability+max.ability)/2.0,min.ability,max.ability)/2.0; rgba = hsva_to_rgba(hsva); glColor4f(rgba.r, rgba.g, rgba.b, rgba.a); i = 6; while (i--) { glBegin(GL_POLYGON); glVertex3f(50.0*i + 1.0, (average.video[i]+min.video[i])/2.0, 20.0); glVertex3f(50.0*i + 1.0, average.video[i] - 0.5, 20.0); glVertex3f(50.0*(i+1) - 1.0, average.video[i+1] - 0.5, 20.0); glVertex3f(50.0*(i+1) - 1.0, (average.video[i+1]+min.video[i+1])/2.0, 20.0); glEnd(); glBegin(GL_POLYGON); glVertex3f(50.0*i + 1.0, (average.video[i]+max.video[i])/2.0, 20.0); glVertex3f(50.0*i + 1.0, average.video[i] + 0.5, 20.0); glVertex3f(50.0*(i+1) - 1.0, average.video[i+1] + 0.5, 20.0); glVertex3f(50.0*(i+1) - 1.0, (average.video[i+1]+max.video[i+1])/2.0, 20.0); glEnd(); } i = USERS; while (i--) { hsva.s = NORMAL(users[ordered[i]].ability,min.ability,max.ability)*0.7+0.3; rgba = hsva_to_rgba(hsva); glColor4f(rgba.r, rgba.g, rgba.b, rgba.a); j = 7; while (j--) { glTranslatef(50.0*j, users[ordered[i]].video[j], 20.0); glutSolidSphere(1.0, 4, 4); glTranslatef(-50.0*j, -users[ordered[i]].video[j], -20.0); } } }void my_keyboard( unsigned char key, int x, int y ) { switch( key ) { case 'y':{ theta_y = (theta_y+1) %360; glutPostRedisplay(); }; break; case 'Y': theta_y = (theta_y-1) % 360; glutPostRedisplay(); break; case 'x':{ theta_x = (theta_x+1) %360; glutPostRedisplay(); }; break; case 'X': theta_x = (theta_x-1) % 360; glutPostRedisplay(); break; case 'q': case 'Q': exit(0) ; default: break; } return ;}void my_display(void) { /* clear the buffer */ /* NEW: now we have to clear depth as well */ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) ; glMatrixMode(GL_MODELVIEW) ; glLoadIdentity(); gluLookAt(150.0, 50.0, 1000.0, // x,y,z coord of the camera 150.0, 50.0, 0.0, // x,y,z coord of the origin 0.0, 1.0, 0.0); // the direction of up (default is y-axis) glTranslatef(150.0,50.0,0.0); glRotatef(theta_y,0,1,0); glRotatef(theta_x,1,0,0); glTranslatef(-150.0,-50.0,0.0); draw_background(); /* buffer is ready */ glutSwapBuffers(); return ;}void my_idle(void) { theta_y = (theta_y+2) %360; glutPostRedisplay(); return ;}void my_TimeOut(int id) { /* right now, does nothing*/ /* schedule next timer event, 20 secs from now */ glutTimerFunc(20000, my_TimeOut, 0); return ;}