//rotating cube program //www.timestocome.com //to link under OSX gcc -framework OpenGL -framework GLUT -o cube cube.c #include #include static GLfloat theta[]= {0.0, 0.0, 0.0}; static GLint axis = 2; GLfloat vertices[][3] = { //the 8 vertices of a cube {-1.0, -1.0, -1.0}, { 1.0, -1.0, -1.0}, { 1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0}, {-1.0, -1.0, 1.0}, { 1.0, -1.0, 1.0}, { 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0} }; GLfloat colors[][3] = { //one color per vertice {0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {1.0, 1.0, 0.0}, {1.0, 0.0, 1.0}, {0.0, 1.0, 1.0}, {1.0, 1.0, 1.0} }; void polygon (int a, int b, int c, int d){ //draw a side of the cube and assign colors glBegin(GL_POLYGON); glColor3fv(colors[a]); glVertex3fv(vertices[a]); glColor3fv(colors[b]); glVertex3fv(vertices[b]); glColor3fv(colors[c]); glVertex3fv(vertices[c]); glColor3fv(colors[d]); glVertex3fv(vertices[d]); glEnd(); } void colorcube(void){ //map vertices to faces //order is very important!! polygon(0, 3, 2, 1); polygon(2, 3, 7, 6); polygon(0, 4, 7, 3); polygon(1, 2, 6, 5); polygon(4, 5, 6, 7); polygon(0, 1, 5, 4); } void display(void){ //display callback, //clear frame buffer and z buffer //rotate cube //and draw //clear viewport buffer (color and depth buffers) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //replace current matrix w/ identity.. // else see shadow/flicker of last image //multiply current matrix by rotation matrix, theta, x, y, z glRotatef(theta[0], 1.0, 0.0, 0.0); glRotatef(theta[1], 0.0, 1.0, 0.0); glRotatef(theta[2], 0.0, 0.0, 1.0); colorcube(); glFlush(); //probably a good idea but no effect on this program glutSwapBuffers(); //put image to be drawn in buffer for display } void spinCube(void){ //idle callback //spin cube 2 degrees theta[axis] += 0.05; //degrees each frame smaller means slower turning cube if(theta[axis] > 360.0){ theta [axis] -= 360.0; } display(); } void mouse(int btn, int state, int x, int y){ //selects an axis to rotate about if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN){axis = 0;} if(btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){axis = 1;} if(btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN){axis = 3;} } void myReshape(int w, int h){ // glViewport( 0, 0, w, h); //sets viewport... not needed here glMatrixMode(GL_PROJECTION);//which matrix stack to perform following ops on glLoadIdentity(); //reduces flicker but no effect in this program if( w <= h){ glOrtho( -2.0, 2.0, -2.0*((GLfloat)h/(GLfloat)w), 2.0*((GLfloat)h/(GLfloat)w), -10.0, 10.0); }else{ glOrtho( -2.0*((GLfloat)w/(GLfloat)h), 2.0*((GLfloat)w/(GLfloat)h), -2.0, 2.0, -10.0, 10.0); } glMatrixMode(GL_MODELVIEW); //switch to operating on modelview matrix } int main(int argc, char **argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize( 500, 500); glutCreateWindow("rotating cube"); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutIdleFunc(spinCube); glutMouseFunc(mouse); glEnable(GL_DEPTH_TEST); //enable hidden surface removal glutMainLoop(); return 0; }