/* * interactive.c * This program illustrates some of the interaction * available with GLUT. */ #include #include // the number of colors we want for the ball #define NUM_COLORS 4 // integer identfiers for the menu items #define INC 0 #define DEC 1 #define CLR 2 #define QUIT 3 // pi #define PI 3.14159 // globals relating to ball properties int ball_speed = 1; int ball_color = 0; float ball_center[2] = {250.0, 250.0}; float ball_dir[2] = {0.2, 0.1}; //other globals float colors[NUM_COLORS][3]; float x_offset; float y_offset; int window_width=500, window_height=500; float ball_radius=40.0; void display(); void menu_callback(int); void init_menus(); void mouse(int, int, int, int); void keybd(unsigned char, int, int); /* * display: This is the display callback function. * Each frame it redraws the ball in its new location, * then updates the ball position taking into account * current speed and direction and hitting walls. It * finally calls glutPostRedisplay to ensure it will get * called again next frame. */ void display() { // clear the screen to get rid of the last ball glClear(GL_COLOR_BUFFER_BIT); // set the color to the current color glColor3fv(colors[ball_color]); // draw a ball (hexagon) glBegin(GL_POLYGON); glVertex2f(ball_center[0] + ball_radius, ball_center[1]); glVertex2f(ball_center[0] + x_offset, ball_center[1] + y_offset); glVertex2f(ball_center[0] - x_offset, ball_center[1] + y_offset); glVertex2f(ball_center[0] - ball_radius, ball_center[1]); glVertex2f(ball_center[0] - x_offset, ball_center[1] - y_offset); glVertex2f(ball_center[0] + x_offset, ball_center[1] - y_offset); glEnd(); // calculate the ball location for the next frame ball_center[0] += ball_dir[0]*ball_speed; ball_center[1] += ball_dir[1]*ball_speed; // check for collisions with side walls if(ball_center[0] > window_width-ball_radius || ball_center[0] < ball_radius) ball_dir[0] = -ball_dir[0]; // check for collisions with top/bottom walls if(ball_center[1] > window_height-ball_radius || ball_center[1] < ball_radius) ball_dir[1] = -ball_dir[1]; // we're using double buffering! glutSwapBuffers(); // make sure this function gets called again next time // through the loop glutPostRedisplay(); } /* * menu_callback: the callback function when a menu item * is selected. Just a big switch statement with an entry * for each menu item. */ void menu_callback(int value) { switch(value){ case INC: ball_speed += 1; break; case DEC: ball_speed -= 1; break; case CLR: ball_color = (ball_color+1) % NUM_COLORS; break; case QUIT: glutDestroyWindow(glutGetWindow()); exit(0); break; default: break; } } /* * init_menus: subroutine to set up the pop-up menu * for this program */ void init_menus() { int my_menu; // create a menu and set callback fn. my_menu = glutCreateMenu(menu_callback); // insert the menu items in order glutAddMenuEntry("Increase speed", INC); glutAddMenuEntry("Decrease speed", DEC); glutAddMenuEntry("Change color", CLR); glutAddMenuEntry("Quit", QUIT); // use the right mouse button to call up the menu glutAttachMenu(GLUT_RIGHT_BUTTON); } void mouse(int button, int state, int x, int y) { int vx, vy; vx = x; vy = window_height - y; if(vx > ball_center[0]-35 && vx < ball_center[0]+35 && vy > ball_center[1]-35 && vy < ball_center[1]+35 && state == GLUT_DOWN) ball_color = (ball_color+1) % NUM_COLORS; } void keybd(unsigned char key, int x, int y) { if(key == '.') ball_speed++; else if(key == ',') ball_speed--; } int main(int argc, char **argv) { /* make window, set coordinate space */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(window_width,window_height); glutInitWindowPosition(100,100); glutCreateWindow("Interactive"); /* set the callback functions */ glutDisplayFunc(display); glutMouseFunc(mouse); glutKeyboardFunc(keybd); gluOrtho2D(0,window_width,0,window_height); /* set up menus */ init_menus(); /* set up colors */ colors[0][0] = 1.0; colors[0][1] = 0.0; colors[0][2] = 0.0; colors[1][0] = 0.0; colors[1][1] = 1.0; colors[1][2] = 0.0; colors[2][0] = 0.0; colors[2][1] = 0.0; colors[2][2] = 1.0; colors[3][0] = 1.0; colors[3][1] = 1.0; colors[3][2] = 1.0; /* set up values for polygon */ x_offset = ball_radius * cos(PI/3.0); y_offset = ball_radius * sin(PI/3.0); /* enter the main loop */ glutMainLoop(); return 0; }