/* planets.c * This program shows how to composite modeling transformations * to draw translated and rotated models. * Interaction: pressing the d and y keys (day and year) * alters the rotation of the planets around the sun. */ #include #include #include static int year = 0; static int day = 0; static int winWidth = 600; static int winHeight = 400; void init(void) /* set up one light (diffuse) */ { GLfloat ambient[] = {0.0, 0.0, 0.0, 1.0}; GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0}; GLfloat specular[] = {1.0, 1.0, 1.0, 1.0}; GLfloat position[] = {0.0, 0.0, -3.0, 1.0}; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, specular); glLightfv(GL_LIGHT0, GL_POSITION, position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glClearColor (0.0, 0.0, 0.0, 0.0); /* black background */ glShadeModel (GL_SMOOTH); } static writeText(GLfloat x, GLfloat y, GLfloat z, GLfloat size, char * msg) { char * p; GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0}; glPushMatrix(); glLoadIdentity (); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glTranslatef(x, y, z); glScalef(size/1000.0, size/1000.0, 0.0); for(p=msg; *p; p++) glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); glPopMatrix(); } void display(void) /* spheres of various colors for light */ { GLfloat red_ambient[] = { 0.4, 0.0, 0.0, 1.0 }; /* red ambient */ GLfloat red_diffuse[] = { 0.6, 0.0, 0.0, 1.0 }; /* red diffuse */ GLfloat blue_ambient[] = { 0.0, 0.0, 0.4, 1.0 }; /* blue ambient */ GLfloat blue_diffuse[] = { 0.0, 0.0, 0.6, 1.0 }; /* blue diffuse */ GLfloat moon_ambient[] = { 0.4, 0.4, 0.4, 1.0 }; /* white ambient */ GLfloat moon_diffuse[] = { 0.6, 0.6, 0.6, 1.0 }; /* white diffuse */ GLfloat sun_ambient[] = { 1.0, 1.0, 0.0, 0.0 }; /* sun ambient */ GLfloat sun_diffuse[] = { 1.0, 1.0, 0.0, 0.0 }; /* sun diffuse */ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glMaterialfv(GL_FRONT, GL_AMBIENT, sun_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_diffuse); glMaterialfv(GL_BACK, GL_AMBIENT, sun_ambient); glMaterialfv(GL_BACK, GL_DIFFUSE, sun_diffuse); glutSolidSphere(1.0, 24, 24); /* draw sun */ glPushMatrix(); glRotatef ((GLfloat)(year%360), 0.0, 1.0, 0.0); glTranslatef (2.0, 0.0, 0.0); glRotatef ((GLfloat)(day%360), 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT, GL_AMBIENT, blue_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, blue_diffuse); glutSolidSphere(0.3, 12, 12); /* draw blue planet */ glPushMatrix(); glRotatef ((GLfloat)((12*year)%360), 0.0, 1.0, 0.0); glTranslatef (0.4, 0.0, 0.0); glRotatef ((GLfloat)((day/30)%360), 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT, GL_AMBIENT, moon_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, moon_diffuse); glutSolidSphere(0.07, 10, 10); /* draw moon */ glPopMatrix(); glPopMatrix(); glPushMatrix(); glRotatef ((GLfloat)((year/2)%360), 0.0, 1.0, 0.0); glTranslatef (3.0, 0.0, 0.0); glRotatef ((GLfloat)((day/2)%360), 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT, GL_AMBIENT, red_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, red_diffuse); glutSolidSphere(0.2, 12, 12); /* draw red planet */ glPopMatrix(); glPopMatrix(); writeText(-1.5, -1.1, -2.0, 1.0, "press and hold y for year, d for day"); glutSwapBuffers(); } void reshape (int w, int h) { winWidth = w; winHeight = h; glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); /* angle aspect near far */ /* -1.0 < Z < -20.0 */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); /* eye X Y Z c X Y Z up X Y Z */ glEnable(GL_DEPTH_TEST); } void keyboard (unsigned char key, int x, int y) { switch (key) { case 'd': day = day + 10; glutPostRedisplay(); break; case 'D': day = day - 10; glutPostRedisplay(); break; case 'y': year = year + 5; glutPostRedisplay(); break; case 'Y': year = year - 5; glutPostRedisplay(); break; case 27: exit(0); break; default: break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (winWidth, winHeight); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }