This OpenGL program displays the sun, earth, and moon as cubes and animates them so that the sun rotates in the middle, the earth spins on its axis and revolves around the sun, and the moon spins and revolves around the earth. The camera uses the same arcball method as that in example 06.
orbit.cc:
// Peter Bui // CSE 40166 Computer Graphics (Fall 2010) // Example 12: orbit #include <cmath> #include <cstdio> #include <cstdlib> #ifdef __APPLE__ #include <GLUT/glut.h> #else #include <GL/glut.h> #endif using namespace std; // Constants ------------------------------------------------------------------- #define WHEEL_UP 3 #define WHEEL_DOWN 4 #define CAMERA_DISTANCE_MIN 50.0 #define CAMERA_DISTANCE_MAX 500.0 // Global variables ------------------------------------------------------------ static size_t WindowWidth = 640; static size_t WindowHeight = 480; static GLint MouseX = 0; static GLint MouseY = 0; static double CameraLatitude = 45.0; static double CameraLongitude = 25.0; static double CameraDistance = 175.0; static double EyeX = -100.0; static double EyeY = 50.0; static double EyeZ = 100.0; static double SunAngle = 0.0; static double SunScale = 25.0; static double EarthRevAngle = 0.0; static double EarthSpinAngle = 0.0; static double EarthScale = 10.0; static double EarthDistance = 2.0 * SunScale; static double MoonRevAngle = 0.0; static double MoonSpinAngle = 0.0; static double MoonScale = 2.5; static double MoonDistance = 1.25 * EarthScale; static GLint FrameRate = 30; static bool AnimationOn = true; // Update camera --------------------------------------------------------------- void update_camera_location() { // Based on some magical math: // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_spherical_coordinates // and some help from Dr. John Stewman double L = CameraDistance * cos(M_PI*CameraLongitude/180.0); EyeX = L * -sin(M_PI*CameraLatitude/180.0); EyeY = CameraDistance * sin(M_PI*CameraLongitude/180.0); EyeZ = L * cos(M_PI*CameraLatitude/180.0); glutPostRedisplay(); } // Initialize scene ------------------------------------------------------------ void init_scene() { glEnable(GL_DEPTH_TEST); glViewport(0, 0, WindowWidth, WindowHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLdouble)WindowWidth/(GLdouble)WindowHeight, 1.0, 750.0); glMatrixMode(GL_MODELVIEW); GLfloat diffuse0[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat ambient0[] = { 0.7, 0.7, 0.7, 1.0 }; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0); glEnable(GL_COLOR_MATERIAL) ; glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); update_camera_location(); } // Display callback ------------------------------------------------------------ void display() { GLfloat position0[] = { EyeX, EyeY, EyeZ, 1.0 }; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLightfv(GL_LIGHT0, GL_POSITION, position0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(EyeX, EyeY, EyeZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // Sun cube glColor3f(0.9, 0.3, 0.0); glPushMatrix(); { glRotatef(SunAngle, 0.0, 1.0, 0.0); glScalef(SunScale, SunScale, SunScale); glutSolidCube(1.0); } glPopMatrix(); // Earth cube glColor3f(0.0, 0.4, 0.8); glPushMatrix(); { glRotatef(EarthRevAngle, 0.0, 1.0, 0.0); glTranslatef(EarthDistance, 0.0, EarthDistance); glPushMatrix(); { glRotatef(EarthSpinAngle, 0.0, 1.0, 0.0); glScalef(EarthScale, EarthScale, EarthScale); glutSolidCube(1.0); } glPopMatrix(); // Moon cube glColor3f(0.8, 0.8, 0.8); glPushMatrix(); { glRotatef(MoonRevAngle, 0.0, 1.0, 0.0); glTranslatef(MoonDistance, 0.0, MoonDistance); glRotatef(MoonSpinAngle, 0.0, 1.0, 0.0); glScalef(MoonScale, MoonScale, MoonScale); glutSolidCube(1.0); } glPopMatrix(); } glPopMatrix(); glutSwapBuffers(); } // Reshape callback ------------------------------------------------------------ void reshape(GLsizei nw, GLsizei nh) { WindowWidth = nw; WindowHeight = nh; init_scene(); } // Keyboard callback ----------------------------------------------------------- void keyboard(unsigned char key, int x, int y) { if (key == 'q' || key == 'Q') exit(EXIT_SUCCESS); if (key == ' ') AnimationOn = !AnimationOn; } // Special callback ----------------------------------------------------------- void special(int key, int x, int y) { switch (key) { case GLUT_KEY_LEFT: CameraLatitude -= 1.0; break; case GLUT_KEY_RIGHT: CameraLatitude += 1.0; break; case GLUT_KEY_UP: CameraLongitude -= 1.0; break; case GLUT_KEY_DOWN: CameraLongitude += 1.0; break; } update_camera_location(); } // Mouse callback -------------------------------------------------------------- void mouse(int button, int state, int x, int y) { MouseX = x; MouseY = y; switch (button) { case WHEEL_UP: CameraDistance = (CameraDistance > CAMERA_DISTANCE_MIN ? CameraDistance - 1.0 : CAMERA_DISTANCE_MIN); break; case WHEEL_DOWN: CameraDistance = (CameraDistance < CAMERA_DISTANCE_MAX ? CameraDistance + 1.0 : CAMERA_DISTANCE_MAX); break; } update_camera_location(); } // Motion callback ------------------------------------------------------------- void motion(int x, int y) { CameraLatitude += 180.0*(double)(x - MouseX)/WindowWidth; CameraLongitude += 180.0*(double)(y - MouseY)/WindowHeight; update_camera_location(); MouseX = x; MouseY = y; } // Timer callback -------------------------------------------------------------- void timer(int value) { if (AnimationOn) { SunAngle = (SunAngle < 360.0 ? SunAngle + 1.0 : 1.0); EarthSpinAngle = (EarthSpinAngle < 360.0 ? EarthSpinAngle + 1.0 : 1.0); EarthRevAngle = (EarthRevAngle < 360.0 ? EarthRevAngle + 2.0 : 1.0); MoonSpinAngle = (MoonSpinAngle < 360.0 ? MoonSpinAngle + 2.0 : 1.0); MoonRevAngle = (MoonRevAngle < 360.0 ? MoonRevAngle + 4.0 : 1.0); } glutPostRedisplay(); glutTimerFunc(1000/FrameRate, timer, 0); } // Main execution -------------------------------------------------------------- int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(WindowWidth, WindowHeight); glutCreateWindow("orbit"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutMouseFunc(mouse); glutMotionFunc(motion); glutTimerFunc(1000/FrameRate, timer, 0); init_scene(); glutMainLoop(); return (EXIT_SUCCESS); } // vim: sts=4 sw=4 ts=8 ft=cpp