700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 利用OpenGL模拟太阳系

利用OpenGL模拟太阳系

时间:2024-04-25 03:50:52

相关推荐

利用OpenGL模拟太阳系

一、实验目的与要求

1、了解OpenGL编程,并熟悉OpenGL的主要功能、绘制流程和基本语法,学会配置OpenGL坏境,并在该环境中编程绘图;

2、利用所学知识(如圆等基本图形的绘制,平移、旋转等三维几何变换,透视投影,三维观察,消隐等),模拟一个动画实体或场景;

3、学会调用OpenGL库中的函数,形成用OpenGL实现预期功能、解决问题的思路,对平时所学知识进行实践,达到融会贯通。

二、实验内容

程序分在5个函数中实现:

1、Initial()

在该函数中,主要通过调用glClearColor(),实现对背景的设置。为了模拟宇宙,达到更好的视觉效果,将背景设置为黑色。

2、ChangeSize()

在该函数中主要实现对视区的设置。通过调用glViewport()函数,对视区尺寸进行设置。通过调用gluPerspective()函数,对透视投影的观察空间进行设置,后期运行时,可根据实际情况随时调整,以达到更好的效果。

3、Display()

该函数是最为重要的函数,大部分功能均在此函数中实现。

首先,通过调用glTranslatef()函数,使初始位置沿z轴负向移动一段距离。

然后,调用glColor3f()函数,选择太阳的颜色。调用glutSolidSphere()函数,绘制太阳。绘制完成后,调用glPushMatrix()函数,保存当前的模型视图矩阵。

之后,由里向外绘制八大行星的公转轨道。调用glColor3f()函数,选定轨道的颜色。调用glSolidTorus()函数,依次改变半径,绘出轨道。

再后,依次从里向外依次绘制水星、金星、地球、火星、木星、土星、天王星、海王星。调用glPopMatrix()函数,恢复模型视图矩阵。调用glPushMatrix()函数,保存当前的模型视图矩阵。调用glColor3f()函数,选择行星的颜色。调用glRotatef()函数,使行星绕z轴旋转一定的角度,即达到公转效果。(公转速度满足离太阳越远,速度越慢的定性规律。)调用glTranslatef()函数,平移一段距离,到达该行星的预定轨道。调用glRotatef()函数,使行星自转。(金星的自转方向与其他行星不同,加以区分。)调用glutSolidSphere()函数,绘制行星。(使得各行星大小,符合定性规律。)同时,对函数glRotatef()中的参数fElect进行循环处理, 增加旋转步长,产生动画效果。

其中,在绘制地球之后,绘制火星之前,进行月球的绘制。月球的绘制与上述行星的绘制过程基本相同。不过,因为月球是以地球为中心公转,故无需调用glPushMatrix()函数。

最后,调用glutSwapBuffers()函数,交换缓冲区,将已渲染好的效果拿出来实现。

4、TimerFunc()

在该函数中,主要通过调用glutTimerFunc()函数,实现对画面的不断刷新,以达到动画的效果。

5、main()

在主函数中,对上述函数进行调用,使程序按期望的效果运行。同时,通过调用glutInitDisplayMode()函数,设置窗口使用RGB颜色、双缓存和深度缓存。通过调用glutCreateWindow()函数,设置运行窗口上显示的标题。

三、实验结果

四、源程序

#include<gl/glut.h>void Initial(){glEnable(GL_DEPTH_TEST); // 启用深度测试glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//背景为黑色}void ChangeSize(int w, int h){if (h == 0)h = 1;glViewport(0, 0, w, h);// 设置视区尺寸glMatrixMode(GL_PROJECTION); // 指定当前操作投影矩阵堆栈glLoadIdentity(); // 重置投影矩阵GLfloat fAspect;fAspect = (float)w / (float)h; // 计算视区的宽高比gluPerspective(88.0, fAspect, 1.0, 500.0); // 指定透视投影的观察空间glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void Display(void){static float fElect1 = 0.0f; // 水星绕太阳旋转的角度static float fElect2 = 0.0f; // 金星绕太阳旋转的角度static float fElect3 = 0.0f; // 地球绕太阳旋转的角度static float fElect4 = 0.0f; // 火星绕太阳旋转的角度static float fElect5 = 0.0f; // 木星绕太阳旋转的角度static float fElect6 = 0.0f; // 土星绕太阳旋转的角度static float fElect7 = 0.0f; // 天王星绕太阳旋转的角度static float fElect8 = 0.0f; // 海王星绕太阳旋转的角度static float fElect9 = 0.0f; // 月球绕地球旋转的角度static float fElect10 = 0.0f; // 除金星外其他星体自转的角度static float fElect11 = 0.0f; // 金星自转的角度glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除颜色和深度缓冲区glMatrixMode(GL_MODELVIEW); // 指定当前操作模型视图矩阵堆栈glLoadIdentity(); // 重置模型视图矩阵glTranslatef(0.0f, 0.0f, -300.0f); //将图形沿z轴负向移动glColor3f(1.0f, 0.1f, 0.1f);//太阳的颜色glutSolidSphere(20.0f, 15, 15);// 绘制太阳glPushMatrix(); // 保存当前的模型视图矩阵glColor3f(0.4f, 0.4f, 0.4f);//行星公转轨道的颜色glutSolidTorus(0.5f, 50.0f, 100, 50);//绘制水星公转轨道glutSolidTorus(0.5f, 80.0f, 100, 50);//绘制金星公转轨道glutSolidTorus(0.5f, 110.0f, 100, 50);//绘制地球公转轨道glutSolidTorus(0.5f, 140.0f, 100, 50);//绘制火星公转轨道glutSolidTorus(0.5f, 170.0f, 100, 50);//绘制木星公转轨道glutSolidTorus(0.5f, 200.0f, 100, 50);//绘制土星公转轨道glutSolidTorus(0.5f, 230.0f, 100, 50);//绘制天王星公转轨道glutSolidTorus(0.5f, 260.0f, 100, 50);//绘制海王星公转轨道glPopMatrix();//恢复模型视图矩阵glPushMatrix(); // 保存当前的模型视图矩阵glColor3f(0.8f, 0.8f, 0.8f); //水星的颜色glRotatef(fElect1, 0.0f, 0.0f, 1.0f); // 公转glTranslatef(50.0f, 0.0f, 0.0f); // 平移一段距离glRotatef(fElect10, 0.0f, 0.0f, 1.0f); //自转glutSolidSphere(7.0f, 15, 15); // 画出水星fElect1 += 12.0f;// 增加旋转步长,产生动画效果if (fElect1 > 360.0f)fElect1 = 12.0f;glPopMatrix(); // 恢复模型视图矩阵glPushMatrix();// 保存当前的模型视图矩阵*/glColor3f(1.0f, 0.55f, 0.0f);//金星的颜色glRotatef(fElect2, 0.0f, 0.0f, 1.0f);//公转glTranslatef(80.0f, 0.0f, 0.0f);// 平移一段距离glRotatef(fElect11, 0.0f, 0.0f, 1.0f); //自转glutSolidSphere(5.0f, 15, 15); // 画出金星fElect2 += 10.0f;// 增加旋转步长,产生动画效果if (fElect2 > 360.0f)fElect2= 10.0f;glPopMatrix(); // 恢复模型视图矩阵glPushMatrix();// 保存当前的模型视图矩阵*/glColor3f(0.0f, 0.0f, 0.55f);//地球的颜色glRotatef(fElect3, 0.0f, 0.0f, 1.0f);//公转glTranslatef(110.0f, 0.0f, 0.0f);// 平移一段距离glRotatef(fElect10, 0.0f, 0.0f, 1.0f);//自转glutSolidSphere(7.0f, 15, 15); // 画出地球fElect3 += 9.0f;// 增加旋转步长,产生动画效果if (fElect3 > 360.0f)fElect3 = 9.0f;glColor3f(1.0f, 1.0f, 0.0f);//月球的颜色glRotatef(fElect9, 0.0f, 0.0f, 1.0f);//公转glTranslatef(10.0f, 0.0f, 0.0f);// 平移一段距离glRotatef(fElect10, 0.0f, 0.0f, 1.0f);//自转glutSolidSphere(2.0f, 15, 15); // 画出月球fElect9 += 100.0f;// 增加旋转步长,产生动画效果if (fElect9 > 360.0f)fElect9 = 100.0f;glPopMatrix(); // 恢复模型视图矩阵glPushMatrix();// 保存当前的模型视图矩阵*/glColor3f(0.82f, 0.41f, 0.12f);//火星的颜色glRotatef(fElect4, 0.0f, 0.0f, 1.0f);//公转glTranslatef(140.0f, 0.0f, 0.0f);// 平移一段距离glRotatef(fElect10, 0.0f, 0.0f, 1.0f);//自转glutSolidSphere(6.0f, 15, 15); // 画出火星fElect4 += 8.0f;// 增加旋转步长,产生动画效果if (fElect4 > 360.0f)fElect4 = 8.0f;glPopMatrix(); // 恢复模型视图矩阵glPushMatrix();// 保存当前的模型视图矩阵*/glColor3f(1.0f, 0.84f, 0.0f);//木星的颜色glRotatef(fElect5, 0.0f, 0.0f, 1.0f);//公转glTranslatef(170.0f, 0.0f, 0.0f);// 平移一段距离glRotatef(fElect10, 0.0f, 0.0f, 1.0f);//自转glutSolidSphere(10.0f, 15, 15); // 画出木星fElect5 += 6.0f;// 增加旋转步长,产生动画效果if (fElect5 > 360.0f)fElect5 = 6.0f;glPopMatrix(); // 恢复模型视图矩阵glPushMatrix();// 保存当前的模型视图矩阵*/glColor3f(0.94f, 0.90f, 0.55f);//土星的颜色glRotatef(fElect6, 0.0f, 0.0f, 1.0f);//公转glTranslatef(200.0f, 0.0f, 0.0f);// 平移一段距离glRotatef(fElect10, 0.0f, 0.0f, 1.0f);//自转glutSolidSphere(9.0f, 15, 15); // 画出土星fElect6 += 4.0f;// 增加旋转步长,产生动画效果if (fElect6 > 360.0f)fElect6 = 4.0f;glPopMatrix(); // 恢复模型视图矩阵glPushMatrix();// 保存当前的模型视图矩阵*/glColor3f(0.0f, 0.81f, 0.82f);//天王星的颜色glRotatef(fElect7, 0.0f, 0.0f, 1.0f);//公转glTranslatef(230.0f, 0.0f, 0.0f);// 平移一段距离glRotatef(fElect10, 0.0f, 0.0f, 1.0f);//自转glutSolidSphere(8.0f, 15, 15); // 画出天王星fElect7 += 3.0f;// 增加旋转步长,产生动画效果if (fElect7 > 360.0f)fElect7 = 3.0f;glPopMatrix(); // 恢复模型视图矩阵glPushMatrix();// 保存当前的模型视图矩阵*/glColor3f(0.39f, 0.58f, 0.93f);//海王星的颜色glRotatef(fElect8, 0.0f, 0.0f, 1.0f); //公转glTranslatef(260.0f, 0.0f, 0.0f);// 平移一段距离glRotatef(fElect10, 0.0f, 0.0f, 1.0f);//自转glutSolidSphere(8.0f, 15, 15); // 画出海王星fElect8 += 2.0f;// 增加旋转步长,产生动画效果if (fElect8 > 360.0f)fElect8 = 2.0f;fElect10 += 1.0f;if (fElect10 > 360.0f)fElect10 = 1.0f;fElect11 += -1.0f;if (fElect10 < -360.0f)fElect11 = -1.0f;glPopMatrix(); // 恢复模型视图矩阵glutSwapBuffers();}void TimerFunc(int value){glutPostRedisplay();glutTimerFunc(100, TimerFunc, 1);}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutCreateWindow("太阳系动画示例");glutReshapeFunc(ChangeSize);glutDisplayFunc(Display);glutTimerFunc(500, TimerFunc, 1);//指定定时器回调函数Initial();glutMainLoop();return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。