/* ** File: clock02.c ** Description: Ticks every half second - using glutTimerFunc ** Rev: 1.0 ** Created: 14 Aug 06 ** Last Update: 14 Aug 06 ** Author: Fran Soddell ** Email: F.Soddell@latrobe.edu.au */ #include #include #include #include #include #define PI 3.14159 /* ** manage GLUT window */ int width = 350; int height = 350; int xPosition = 100; int yPosition = 100; /* ** manage world coordinates */ GLdouble xLeft = -1.0; GLdouble xRight = 1.0; GLdouble yBottom = -1.0; GLdouble yTop = 1.0; /* ** manage rgb colours */ enum { black, green, orange, white }; typedef GLfloat colourType[3]; colourType colour[]={ {0.0, 0.0, 0.0}, {0.0, 0.9, 0.0}, {1.000, 0.549, 0.000}, {1.0, 1.0, 1.0} }; /* ** manage model(s) */ typedef GLdouble vertexType [2]; # define NUM_VERTICES_FOR_SQUARE 4 vertexType square[]={ {0.5,0.5},{-0.5,0.5},{-0.5,-0.5},{0.5,-0.5} }; enum { x, y }; #define FACE_SIDES 64 #define HOURS 12 vertexType clockFace[FACE_SIDES]; vertexType hours[HOURS]; GLdouble xClockCentre = 0.0; GLdouble yClockCentre = 0.0; int currentHour = 3; /* ** manage transforms */ GLdouble ra = 0; GLdouble angleIncrement = 0.5; /* ** manage animation */ int milliseconds = 500; GLboolean isRotating = GL_FALSE; /* ** *********************************************************** */ /* ** Compute the vertices for an ngon of any size. ** IN: ngon - pointer to an array of vertexType ** numSides - number of sides for the ngon ** xCentre, yCentre - world coordinates of centre of ngon ** radius - length of radius of the circle */ void computeVertices(vertexType * ngon, GLint numSides, GLdouble xCentre, GLdouble yCentre, GLdouble radius){ int i; GLdouble angle; /* ** angle in radians is the circumference of circle ** divided by the number of sides for the ngon */ angle = 2 * PI / numSides; /* ** Calculate equidistant points on the circumference ** of the circle with centre xCentre, yCentre ** and place the x and y coordinate values in ngon array */ for(i = 0; i < numSides; i++){ ngon[i][x] = xCentre + radius * cos(i * angle); ngon[i][y] = yCentre + radius * sin(i * angle); } } /* ** Function to render an OpenGL primitive. ** IN: an image array of vertexType, the number of vertices in the array, ** and the type of OpenGL primitive to be rendered. ** OUT: */ void render(vertexType * image, int numVertices, int primitive){ int i; glBegin(primitive); for(i=0;i= 360.0) ra = 0.0; } /* ** GLUT callback function ** Called whenever an ordinary key is pressed by the user. ** IN: char value of key pressed, x and y position of the mouse ** OUT: */ void keyboard(unsigned char key,int xMouse,int yMouse){ switch(key){ /* 27 is the integer value of the Esc key */ case 27: exit(EXIT_SUCCESS); case 'm': printf("%s%d%s%d\n","x=",xMouse," y=",yMouse); break; /* increase the rotation angle for the square */ case 'r': rotateSquare(); break; /* if the input key is not handled, display it */ default: printf("%s%c\n","key=",key); } glutPostRedisplay(); } /* ** TODO: add comments */ void setProjection(void){ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(xLeft, xRight, yBottom, yTop); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* ** TODO: add comments */ void renderClock(void){ glColor3fv(colour[green]); render(clockFace, FACE_SIDES, GL_POLYGON); glColor3fv(colour[black]); glBegin(GL_LINES); glVertex2d(xClockCentre, yClockCentre); glVertex2dv(hours[currentHour]); glEnd(); } /* ** GLUT callback function ** This is called to render the graphics display in the GLUT window. */ void display(void){ setProjection(); /* ** Clear the window with the background colour before ** (re)rendering. */ glClear(GL_COLOR_BUFFER_BIT); glColor3fv(colour[orange]); glPushMatrix(); glRotated(ra, 0, 0, 1); render(square,NUM_VERTICES_FOR_SQUARE,GL_POLYGON); glPopMatrix(); renderClock(); /* ** Swap the back buffer into the front. */ glutSwapBuffers(); } /* ** GLUT callback function ** called first when a GLUT window is created ** then called every time the window is resized by the user ** IN: w - the current width of the window ** h - the current height of the window */ void reshape(int w, int h){ width = w; height = h; } /* ** TODO: COMMENTS */ void delay(int milliseconds){ clock_t oldTick; clock_t newTick; double difference = 0; int i; oldTick = clock(); while(difference < milliseconds){ newTick = clock(); difference = (double) (newTick - oldTick); } } /* ** TODO: COMMENTS */ void timer(int id){ switch(id){ case 1: glClearColor(0.9, 0.9, 0.7, 0.0); if(isRotating){ rotateSquare(); if(currentHour == 0) currentHour = 11; else currentHour--; glutTimerFunc(milliseconds, timer, 1); glutPostRedisplay(); } break; case 3: glClearColor(1.0, 0.0, 0.0, 0.0); glutTimerFunc(10000, timer, 3); glutPostRedisplay(); break; case 2: exit(EXIT_SUCCESS); } } /* ** TODO: COMMENTS */ void mouse(int button, int state, int xMouse, int yMouse){ static int moving = GL_FALSE; if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) if(moving){ isRotating = !isRotating; moving = GL_FALSE; } else{ isRotating = !isRotating; glutTimerFunc(milliseconds, timer, 1); moving = GL_TRUE; } else if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){ glutTimerFunc(milliseconds, timer, 3); printf("xMouse=%d yMouse=%d\n", xMouse, yMouse); //glutTimerFunc(milliseconds, timer, 3); } else if(button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN){ printf("THREE SECONDS TO SHUT DOWN"); glutTimerFunc(1000, timer, 2); } } /* ** initialise GLUT ** IN: argc - number of command line arguments ** argv - array of arguments */ void setUpGLUT(int argc,char ** argv){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(width, height); glutInitWindowPosition(xPosition, yPosition); glutCreateWindow("Counting Half Seconds"); /* ** Register callbacks. */ glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutReshapeFunc(reshape); glutMouseFunc(mouse); } /* ** initialise OpenGL */ void initialiseGL(void){ /* ** Set the background colour ** (clear colour) to white. */ glClearColor(1,1,1,0.0); } int main(int argc,char ** argv){ computeVertices(clockFace, FACE_SIDES, xClockCentre, yClockCentre, 0.3); computeVertices(hours, HOURS, xClockCentre, yClockCentre, 0.27); setUpGLUT(argc,argv); initialiseGL(); /* ** Display window and enter the GLUT event ** processing loop. */ glutMainLoop(); /* ** Return success code to operating system. ** Required ANSI standard C code. ** EXIT_SUCCESS defined in stdlib.h */ return EXIT_SUCCESS; }