/* simple5.c based on simple5.c, draws a polygon with n vertices, where n can be increased and decreased with key strokes Laura Toma */ #include #include #include #include #ifdef __APPLE__ #include #else #include #endif GLfloat red[3] = {1.0, 0.0, 0.0}; GLfloat green[3] = {0.0, 1.0, 0.0}; GLfloat blue[3] = {0.0, 0.0, 1.0}; GLfloat black[3] = {0.0, 0.0, 0.0}; GLfloat white[3] = {1.0, 1.0, 1.0}; GLfloat gray[3] = {0.5, 0.5, 0.5}; GLfloat yellow[3] = {1.0, 1.0, 0.0}; GLfloat magenta[3] = {1.0, 0.0, 1.0}; GLfloat cyan[3] = {0.0, 1.0, 1.0}; GLint fillmode = 0; float r = .1; //initial radius int n = 6; const int DECREASING = 0; const int INCREASING = 1; int mode = INCREASING; //whether the radius is increasing or decreasing /* we keep track globally of the coordinates of the center of the rectangle; they will be updated by the keys that implement move left and right */ GLfloat x_center = 0.0, y_center = 0.0; /* forward declarations of functions */ void display(void); void keypress(unsigned char key, int x, int y); void main_menu(int value); void timerfunc(); int main(int argc, char** argv) { /* open a window */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutInitWindowPosition(100,100); glutCreateWindow(argv[0]); /* OpenGL init */ glClearColor(0, 0, 0, 0); /* set background color black*/ /* callback functions */ glutDisplayFunc(display); glutKeyboardFunc(keypress); glutIdleFunc(timerfunc); glutCreateMenu(main_menu); glutAddMenuEntry("Fill/Outline", 1); glutAddMenuEntry("Quit", 2); glutAttachMenu(GLUT_RIGHT_BUTTON); /* event handler */ glutMainLoop(); return 0; } void draw_hexagon() { int i; float a = 2*M_PI/n; if (fillmode) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } /* draw a polygon centered at x_center, y_center */ glBegin(GL_POLYGON); for (i=0; i<= n; i++) { glVertex2f(r*cos(a*i), r*sin(a*i)); } glEnd(); } void draw_polygon(){ if (fillmode) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } /* draw a polygon centered at x_center, y_center */ glBegin(GL_POLYGON); glColor3fv(blue); glVertex2f(x_center - 0.5, y_center -0.5); glColor3fv(white); glVertex2f(x_center -0.5, y_center + 0.5); glColor3fv(red); glVertex2f(x_center + 0.5, y_center + 0.5); glColor3fv(gray); glVertex2f(x_center + 0.5, y_center -0.5); glEnd(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //draw_polygon(); draw_hexagon(); /* execute the drawing commands */ glFlush(); } void keypress(unsigned char key, int x, int y) { switch(key) { case 'q': exit(0); break; case '+': r *= 1.1; glutPostRedisplay(); break; case '-': r *= .9; glutPostRedisplay(); break; case '<': n--; glutPostRedisplay(); break; case '>': n++; glutPostRedisplay(); break; case 'l': x_center -= 0.2; glutPostRedisplay(); break; case 'r': x_center += 0.2; glutPostRedisplay(); break; case 'u': y_center += 0.2; glutPostRedisplay(); break; case 'd': y_center -= 0.2; glutPostRedisplay(); break; } } void main_menu(int value) { switch (value){ case 1: /* toggle outline/fill */ fillmode = !fillmode; break; case 2: exit(0); } glutPostRedisplay(); } void timerfunc() { static int lastFrameTime=0; //note: a static variable, remembered from one call to the next int now, elapsed_ms; now = glutGet (GLUT_ELAPSED_TIME); elapsed_ms = now - lastFrameTime; lastFrameTime=now; //LT: on my desktop the timerfunc is called every millisecond, so i //want to increase the radius about 1.001 per millisecond. On slower //computers, the interrupt may be less frequent, so i made the modifier //depend on teh elapsed time if (mode == INCREASING && r >1) { mode = DECREASING; } if (mode == DECREASING && r < .1) { mode = INCREASING; } if (mode == INCREASING) r *= (1 + 1/1000.0*elapsed_ms); if (mode == DECREASING) r /= (1 + 1/1000.0*elapsed_ms); glutPostRedisplay(); }