效果图如上:
步骤:请看注释,这里略。
实现代码如下:
1 #include "windows.h" 2 #include <gl\glut.h> 3 4 // 三者的大小比例 5 #define SunSize 0.4 6 #define EarthSize 0.06 7 #define MoonSize 0.016 8 9 GLfloat SpeedMultiplicator = 0.01;// 运行倍数 10 // 时间比例 11 GLfloat DaysPerYear = 365.24; //OK, ok... but it is soo slow with 360! 12 GLfloat DaysPerMoon = 27.321; // 月球公转一圈的天数 13 //degrees 累计角度 14 GLfloat EarthAroundSun = 0.0; 15 GLfloat EarthItsSelf = 0.0; 16 GLfloat moonAroundEarth = 0.0; 17 GLfloat moonItsSelf = 0.0; 18 // 半径 19 GLfloat EarthOrbitRadius = 1.0; // 地球轨道半径 20 GLfloat MoonOrbitRadius = 0.15;// 月球轨道半径 21 // 角速度 22 GLfloat EarthItsSelfSpeed = 360.0 / 1.0 * SpeedMultiplicator; // 以一天为单位时间 23 GLfloat moonAroundEarthSpeed = 360.0 / DaysPerMoon * SpeedMultiplicator; 24 GLfloat moonItsSelfSpeed = moonAroundEarthSpeed; // 月球同步自转 25 GLfloat EarthAroundSunSpeed = 360.0 / DaysPerYear * SpeedMultiplicator; 26 27 void RenderScene(void) 28 { 29 glPushMatrix(); // 压栈1 30 gluLookAt( 0.0,3.0,3.0, // 眼睛的位置 z轴+y轴=45% 31 0.0,-1.0,-1.0, // 眼睛的朝向的位置 z轴+y轴=45% 32 0.0,1.0,0.0); // 相片朝上的方向(因为你可以歪着头看同一个物体) y轴 33 glColor3f(1.0,1.0,0.5); 34 glutWireSphere(SunSize,20,20); // 绘制太阳 35 36 glPushMatrix(); // 压栈2 37 glRotatef(EarthAroundSun,0.0,1.0,0.0); // 地球公转的轨道角度 y轴 38 glTranslatef(EarthOrbitRadius,0.0,0.0);// 地球轨道半径 39 glRotatef(-EarthAroundSun,0.0,1.0,0.0); 40 41 glPushMatrix(); // 压栈3 42 glRotatef(EarthItsSelf,0.4348,1.0,0.0); // 地球自转的轨道角度 43 glColor3f(0.0,0.5,0.8); 44 glutWireSphere(EarthSize,8,8); //Draw earth 绘制地球 45 //Draw earth rotation axis 地球自转轴线 46 glLineStipple (0.1, 0x0F0F); // 虚化线 部分1 47 glEnable(GL_LINE_STIPPLE); // 虚化线 部分2 48 glBegin(GL_LINES); // 直线 49 glVertex3f(0.1087,0.25,0.0); 50 glVertex3f(-0.1087,-0.25,0.0); 51 glEnd(); 52 glDisable(GL_LINE_STIPPLE); // 虚化线 部分3 53 54 glPopMatrix(); // 出栈3 55 56 // 恢复到 地球球心的坐标系 57 glRotatef(moonAroundEarth,0.0,1.0,0.0); // 月球环绕地球的轨道角度 58 glTranslatef(MoonOrbitRadius,0.0,0.0); // 月球轨道半径 > 地球大小半径 59 //The following 2 lines should be combined, but it is better to understand this way 60 glRotatef(-moonAroundEarth,0.0,1.0,0.0); // 月球沿着Y轴逆时针自转 61 glRotatef(moonItsSelf,0.0,1.0,0.0); // 月球沿着Y轴顺时针自转 62 glColor3f(0.8,0.8,0.75); // 设置颜色 63 glutWireSphere(MoonSize,8,8); // 绘制球体 64 glPopMatrix();// 出栈2 65 66 // 恢复到 太阳球心的坐标系 67 glPopMatrix();// 出栈1 68 69 } 70 71 void Init(void) 72 { 73 glClearColor(0.0,0.0,0.0,0.0);// 清除颜色 74 glClearDepth(10.0); // 清除深度 75 glMatrixMode(GL_MODELVIEW);// 模型矩阵 76 glLoadIdentity();// 把视景体截取的图像按特殊处理显示到屏幕上 77 } 78 79 void Display(void) 80 { 81 glClear(GL_COLOR_BUFFER_BIT); 82 RenderScene(); // 渲染 83 glFlush(); 84 glutSwapBuffers(); 85 } 86 87 void Reshape(int x, int y) 88 { 89 if (y == 0) return; 90 glMatrixMode(GL_PROJECTION); // 投影矩阵 91 glLoadIdentity(); 92 gluPerspective(30.0,(GLdouble)x/(GLdouble)y,0.8,10.0); // 设定投影变换 93 glMatrixMode(GL_MODELVIEW); // 模型矩阵 94 glViewport(0,0,x,y); // 把视景体截取的图像按特殊处理显示到屏幕上 95 Display(); 96 } 97 static long long times = 0; 98 void Idle(void) 99 { 100 times++; // 延迟 101 if(times>50000) 102 times =0; 103 if(times% 50000== 0) 104 { 105 EarthItsSelf += EarthItsSelfSpeed; // 一天的速度 106 EarthAroundSun += EarthAroundSunSpeed; // 一年的速度 107 moonItsSelf += moonItsSelfSpeed; // 月球自转的转速 108 moonAroundEarth += moonAroundEarthSpeed; // 月球围绕地球的转速 109 Display(); 110 } 111 } 112 113 114 int main(int argc, char* argv[]) 115 { 116 glutInit(&argc, argv); 117 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 118 glutInitWindowSize(800,600); 119 glutCreateWindow(argv[0]); 120 Init(); 121 glutReshapeFunc(Reshape); 122 glutDisplayFunc(Display); 123 glutIdleFunc(Idle); 124 glutMainLoop(); 125 return 0; 126 }