利用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;
}
视点变换,旋转,加速减速,星空背景 太阳,光晕 各行星纹理 #include #include #include #include #include #include #include #pragma comment(lib, "winmm.lib") #pragma comment(lib,"wininet") // 纹理图像结构 typedef struct { int imgWidth; // 纹理宽度 int imgHeight; // 纹理高度 unsigned char byteCount; // 每个象素对应的字节数,3:24位图,4:带alpha通道的24位图 unsigned char *data; // 纹理数据 }TEXTUREIMAGE; // BMP文件头 #pragma pack(2) typedef struct { unsigned short bfType; // 文件类型 unsigned long bfSize; // 文件大小 unsigned short bfReserved1; // 保留位 unsigned short bfReserved2; // 保留位 unsigned long bfOffBits; // 数据偏移位置 }BMPFILEHEADER; #pragma pack() // BMP信息头 typedef struct { unsigned long biSize; // 此结构大小 long biWidth; // 图像宽度 long biHeight; // 图像高度 unsigned short biPlanes; // 调色板数量 unsigned short biBitCount; // 每个象素对应的位数,24:24位图,32:带alpha通道的24位图 unsigned long biCompression; // 压缩 unsigned long biSizeImage; // 图像大小 long biXPelsPerMeter;// 横向分辨率 long biYPelsPerMeter;// 纵向分辨率 unsigned long biClrUsed; // 颜色使用数 unsigned long biClrImportant; // 重要颜色数 }BMPINFOHEADER; // 定义窗口的标题、宽度、高度、全屏布尔变量 #define WIN_TITLE "模拟太阳系各星球的转动" const int WIN_WIDTH = 800; const int WIN_HEIGHT = 600; BOOL isFullScreen = FALSE; // 初始不为全屏 #define DEG_TO_RAD 0.017453 float angle=0.0; static GLdouble viewer[]= {0,0,0,0,0}; // 初始化视角 GLUquadricObj *quadric; // 建立二次曲面对象 GLfloat angle_Z; // 星空旋转角度 bool g_bOrbitOn = true; // 控制转动暂停 float g_fSpeedmodifier = 1.0f; // 时间控制 float g_fElpasedTime; double g_dCurrentTime; double g_dLastTime; GLfloat LightAmbient[] = { 1.0f, 1.0f, 1.0f, 0.0f }; // 环境光参数 GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 0.0f }; // 漫射光参数 GLfloat LightPosition[] = { 0.0f, 0.0f, 0.0f, 1.0f }; // 光源的位置 // 纹理图象 TEXTUREIMAGE skyImg; TEXTUREIMAGE sunImg; TEXTUREIMAGE rayImg; TEXTUREIMAGE mercuImg; TEXTUREIMAGE venusImg; TEXTUREIMAGE earthImg; TEXTUREIMAGE marsImg; TEXTUREIMAGE jupiterImg; TEXTUREIMAGE saturnImg; TEXTUREIMAGE uranusImg; TEXTUREIMAGE neptuneImg; TEXTUREIMAGE moonImg; GLuint texture[12]; // 纹理数组 // 星球速度定义 static float fSunSpin = 0.0f; // 太阳自转速度 static float fMercuSpin = 0.0f; // 水星自转速度 static float fMercuOrbit = 0.0f; // 水星公转速度 static float fVenusSpin = 0.0f; // 金星自转速度 static float fVenusOrbit = 0.0f; // 金星公转速度 static float fEarthSpin = 0.0f; // 地球自转速度 static float fEarthOrbit = 0.0f; // 地球公转速度 static float fMarsSpin = 0.0f; // 火星自转速度 static float fMarsOrbit = 0.0f; // 火星公转速度 static float fJupiterSpin = 0.0f; // 木星自转速度 static float fJupiterOrbit = 0.0f; // 木星公转速度 static float fSaturnSpin = 0.0f; // 土星自转速度 static float fSaturnOrbit = 0.0f; // 土星公转速度 static float fUranusSpin = 0.0f; // 天王星自转速度 static float fUranusOrbit = 0.0f; // 天王星公转速度 static float fNeptuneSpin = 0.0f; // 海王星自转速度 static float fNeptuneOrbit = 0.0f; // 海王星公转速度 static float fMoonSpin = 0.0f; // 月亮自转速度 static float fMoonOrbit = 0.0f; // 月亮公转速度 void MakeTexture(TEXTUREIMAGE textureImg, GLuint * texName) //转换为纹理 { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //对齐像素字节函数 glGenTextures(1,texName); //第一个参数指定表明获取多少个连续的纹理标识符 glBindTexture(GL_TEXTURE_2D , *texName); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureImg.imgWidth,textureImg.imgHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, textureImg.data); } // 初始化OpenGL void InitGL(void) { glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //设置黑色背景 glClearDepth(2.0f); // 设置深度缓存 glEnable(GL_DEPTH_TEST); //启动深度测试 glDepthFunc(GL_LEQUAL); //深度小或相等的时候渲染 glShadeModel(GL_SMOOTH); //启动阴影平滑 glEnable(GL_CULL_FACE); //开启剔除操作效果 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //使用质量最好的模式指定颜色和纹理坐标的插值质量 glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 设置环境光 glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 设置漫反射光 glEnable(GL_LIGHTING); // 打开光照 glEnable(GL_LIGHT1); // 打开光源1 // 载入纹理 glEnable(GL_TEXTURE_2D); // 开启2D纹理映射 MakeTexture(skyImg, &texture;[0]); MakeTexture(sunImg, &texture;[1]); MakeTexture(rayImg, &texture;[2]); MakeTexture(mercuImg, &texture;[3]); MakeTexture(venusImg, &texture;[4]); MakeTexture(earthImg, &texture;[5]); MakeTexture(marsImg, &texture;[6]); MakeTexture(jupiterImg, &texture;[7]); MakeTexture(saturnImg, &texture;[8]); MakeTexture(uranusImg, &texture;[9]); MakeTexture(neptuneImg, &texture;[10]); MakeTexture(moonImg, &texture;[11]); quadric = gluNewQuadric(); // 建立一个曲面对象指针 gluQuadricTexture(quadric, GLU_TRUE); // 建立纹理坐标 gluQuadricDrawStyle(quadric, GLU_FILL); // 面填充 } void Display(void) { glLoadIdentity(); // 设置观察点的位置和观察的方向 gluLookAt(viewer[0],viewer[1],viewer[2],viewer[3],viewer[4],-5,0,1,0); //摄像机x,摄像机y,摄像机z, 目标点x,目标点y,目标点z, 摄像机顶朝向x,摄像机顶朝向y,摄像机顶朝向z // 获得系统时间使太阳系有动态效果 g_dCurrentTime = timeGetTime(); g_fElpasedTime = (float)((g_dCurrentTime - g_dLastTime) * 0.0005); g_dLastTime = g_dCurrentTime; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); //指定GL_MODELVIEW是下一个矩阵操作的目标 glTranslatef(0.0f, 0.0f, -5.0f); // 将坐标系移入屏幕5.0f glRotatef(10, 1.0f ,0.0f, 0.0f); // 将坐标系绕x轴旋转10度 glEnable(GL_LIGHT0); // 打开光源0 /**********************************绘制背景星空********************************************/ glPushMatrix (); // 当前模型矩阵入栈 glTranslatef(-10.0f, 3.0f, 0.0f); glRotatef(angle_Z, 0.0f, 0.0f, 1.0f); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture[0]); // 星空纹理 glBegin(GL_QUADS); glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-50.0f, -50.0f, -50.0f); glTexCoord2f(6.0f, 0.0f); glVertex3f( 50.0f, -50.0f, -50.0f); glTexCoord2f(6.0f, 6.0f); glVertex3f( 50.0f, 50.0f, -50.0f); glTexCoord2f(0.0f, 6.0f); glVertex3f(-50.0f, 50.0f, -50.0f); glEnd(); glBegin(GL_QUADS); glNormal3f( 0.0f, 0.0f, -1.0f); glTexCoord2f(6.0f, 6.0f); glVertex3f(-50.0f, -50.0f, 50.0f); glTexCoord2f(0.0f, 6.0f); glVertex3f( 50.0f, -50.0f, 50.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 50.0f, 50.0f, 50.0f); glTexCoord2f(6.0f, 0.0f); glVertex3f(-50.0f, 50.0f, 50.0f); glEnd(); glBegin(GL_QUADS); glNormal3f( 0.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-50.0f, -50.0f, -50.0f); glTexCoord2f(6.0f, 6.0f); glVertex3f( 50.0f, -50.0f, 50.0f); glTexCoord2f(6.0f, 0.0f); glVertex3f( 50.0f, -50.0f, -50.0f); glTexCoord2f(0.0f, 6.0f); glVertex3f(-50.0f, -50.0f, 50.0f); glEnd(); glBegin(GL_QUADS); glNormal3f( 0.0f, -1.0f, 0.0f); glTexCoord2f(6.0f, 6.0f); glVertex3f(-50.0f, 50.0f, -50.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 50.0f, 50.0f, 50.0f); glTexCoord2f(0.0f, 6.0f); glVertex3f( 50.0f, 50.0f, -50.0f); glTexCoord2f(6.0f, 0.0f); glVertex3f(-50.0f, 50.0f, 50.0f); glEnd(); glBegin(GL_QUADS); glNormal3f( 1.0f, 0.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-50.0f, -50.0f, -50.0f); glTexCoord2f(6.0f, 6.0f); glVertex3f(-50.0f, 50.0f, 50.0f); glTexCoord2f(0.0f, 6.0f); glVertex3f(-50.0f, -50.0f, 50.0f); glTexCoord2f(6.0f, 0.0f); glVertex3f(-50.0f, 50.0f, -50.0f); glEnd(); glBegin(GL_QUADS); glNormal3f( -1.0f, 0.0f, 0.0f); glTexCoord2f(6.0f, 6.0f); glVertex3f(50.0f, -50.0f, -50.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(50.0f, 50.0f, 50.0f); glTexCoord2f(6.0f, 0.0f); glVertex3f(50.0f, -50.0f, 50.0f); glTexCoord2f(0.0f, 6.0f); glVertex3f(50.0f, 50.0f, -50.0f); glEnd(); glPopMatrix (); // 当前模型矩阵出栈 /**********************************绘制太阳************************************************/ glBindTexture(GL_TEXTURE_2D, texture[2]); // 光晕纹理 glEnable(GL_BLEND); // 开启混合 glDisable(GL_DEPTH_TEST); // 关闭深度测试 // 绘制太阳光晕 glDisable(GL_LIGHTING); // 关闭光照 glBlendFunc(GL_SRC_ALPHA,GL_ONE); // 半透明混合函数 glColor4f(1.0f, 0.5f, 0.0f, 0.5f); // 设置RGBA值 glBegin(GL_QUADS); glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glEnd(); glDisable(GL_BLEND); // 关闭混合 glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); // 开启光照 glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); // 设置光源1位置 glBindTexture(GL_TEXTURE_2D, texture[1]); // 太阳纹理 // 将坐标系绕Y轴旋转fSunSpin角度,控制太阳自转 glRotatef(fSunSpin,0.0,1.0,0.0); gluSphere(quadric, 0.3f, 32, 32); // 绘制太阳球体 /**********************************绘制水星************************************************/ glDisable(GL_LIGHT0); glEnable(GL_TEXTURE_2D ); // 开启纹理 glPushMatrix (); // 当前模型视图矩阵入栈 // 将坐标系绕Y轴旋转fMercuOrbit角度,控制水星公转 glRotatef(fMercuOrbit, 0.0f, 1.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度 glTranslatef(0.5f, 0.0f, 0.0f); // 将坐标系右移0.5f glBindTexture(GL_TEXTURE_2D, texture[3]); // 水星纹理 // 将坐标系绕Z轴旋转fMercuSpin角度 控制水星自转 glRotatef(fMercuSpin , 0.0f, 0.0f, 1.0f); gluSphere(quadric, 0.04f, 32, 32); // 水星球体 glPopMatrix (); // 当前模型视图矩阵出栈 // 绘制轨道 glBegin(GL_LINE_LOOP); for(angle=0;angle<=360;angle++) glVertex3f(0.5f*sin(DEG_TO_RAD*angle),0,0.5f*cos(DEG_TO_RAD*angle)); glEnd(); /**********************************绘制金星************************************************/ glDisable(GL_LIGHT0); glEnable(GL_TEXTURE_2D ); // 开启纹理 glPushMatrix (); // 当前模型视图矩阵入栈 // 将坐标系绕Y轴旋转fVenusOrbit角度,控制金星公转 glRotatef(fVenusOrbit , 0.0f, 1.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);// 将坐标系绕X轴旋转-90度 glTranslatef(0.8f, 0.0f, 0.0f); // 将坐标系右移0.8f glBindTexture(GL_TEXTURE_2D, texture[4]); // 金星纹理 // 将坐标系绕Z轴旋转fVenusSpin角度,控制金星自转 glRotatef(fVenusSpin , 0.0f, 0.0f, 1.0f); gluSphere(quadric, 0.06f, 32, 32); // 金星球体 glPopMatrix (); glBegin(GL_LINE_LOOP); for(angle=0;angle<=360;angle++) glVertex3f(0.8f*sin(DEG_TO_RAD*angle),0,0.8f*cos(DEG_TO_RAD*angle)); glEnd(); /**********************************绘制地球************************************************/ glDisable(GL_LIGHT0); glEnable(GL_TEXTURE_2D ); // 开启纹理 glPushMatrix (); // 当前模型视图矩阵入栈 // 将坐标系绕Y轴旋转fEarthOrbit角度,控制地球公转 glRotatef(fEarthOrbit , 0.0f, 1.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);// 将坐标系绕X轴旋转-90度 glTranslatef(1.1f, 0.0f, 0.0f); // 将坐标系右移1.1f glBindTexture(GL_TEXTURE_2D, texture[5]); // 地球纹理 // 将坐标系绕Z轴旋转fEarthSpin角度,控制地球自转 glRotatef(fEarthSpin , 0.0f, 0.0f, 1.0f); gluSphere(quadric, 0.08f, 32, 32); // 地球球体 glPopMatrix (); glBegin(GL_LINE_LOOP); for(angle=0;angle<=360;angle++) glVertex3f(1.1f*sin(DEG_TO_RAD*angle),0,1.1f*cos(DEG_TO_RAD*angle)); glEnd(); /**********************************绘制火星************************************************/ glDisable(GL_LIGHT0); glEnable(GL_TEXTURE_2D ); // 开启纹理 glPushMatrix (); // 当前模型视图矩阵入栈 // 将坐标系绕Y轴旋转fMarsOrbit角度,控制火星公转 glRotatef(fMarsOrbit , 0.0f, 1.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度 glTranslatef(1.4f, 0.0f, 0.0f); // 将坐标系右移1.4f glBindTexture(GL_TEXTURE_2D, texture[6]); // 火星纹理 // 将坐标系绕Z轴旋转fMarsSpin角度,控制火星自转 glRotatef(fMarsSpin , 0.0f, 0.0f, 1.0f); gluSphere(quadric, 0.04f, 32, 32); // 火星球体 glPopMatrix (); glBegin(GL_LINE_LOOP); for(angle=0;angle<=360;angle++) glVertex3f(1.4f*sin(DEG_TO_RAD*angle),0,1.4f*cos(DEG_TO_RAD*angle)); glEnd(); /**********************************绘制木星************************************************/ glDisable(GL_LIGHT0); glEnable(GL_TEXTURE_2D ); // 开启纹理 glPushMatrix (); // 当前模型视图矩阵入栈 // 将坐标系绕Y轴旋转fJupiterOrbit角度,控制木星公转 glRotatef(fJupiterOrbit , 0.0f, 1.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度 glTranslatef(1.7f, 0.0f, 0.0f); // 将坐标系右移1.7f glBindTexture(GL_TEXTURE_2D, texture[7]); // 木星纹理 // 将坐标系绕Z轴旋转fJupiterSpin角度,控制木星自转 glRotatef(fJupiterSpin , 0.0f, 0.0f, 1.0f); gluSphere(quadric, 0.13f, 32, 32); // 木星球体 glPopMatrix (); glBegin(GL_LINE_LOOP); for(angle=0;angle<=360;angle++) glVertex3f(1.7f*sin(DEG_TO_RAD*angle),0,1.7f*cos(DEG_TO_RAD*angle)); glEnd(); /**********************************绘制土星************************************************/ glDisable(GL_LIGHT0); glEnable(GL_TEXTURE_2D ); // 开启纹理 glPushMatrix (); // 当前模型视图矩阵入栈 // 将坐标系绕Y轴旋转fSaturnOrbit角度,控制土星公转 glRotatef(fSaturnOrbit , 0.0f, 1.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度 glTranslatef(1.9f, 0.0f, 0.0f); // 将坐标系右移1.9f glBindTexture(GL_TEXTURE_2D, texture[8]); // 土星纹理 // 将坐标系绕Z轴旋转fSaturnSpin角度,控制土星自转 glRotatef(fSaturnSpin , 0.0f, 0.0f, 1.0f); gluSphere(quadric, 0.1f, 32, 32); // 土星球体 glPopMatrix (); glBegin(GL_LINE_LOOP); for(angle=0;angle<=360;angle++) glVertex3f(1.9f*sin(DEG_TO_RAD*angle),0,1.9f*cos(DEG_TO_RAD*angle)); glEnd(); /**********************************绘制天王星**********************************************/ glDisable(GL_LIGHT0); glEnable(GL_TEXTURE_2D ); // 开启纹理 glPushMatrix (); // 当前模型视图矩阵入栈 // 将坐标系绕Y轴旋转fUranusOrbit角度,控制天王星公转 glRotatef(fUranusOrbit , 0.0f, 1.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度 glTranslatef(2.1f, 0.0f, 0.0f); // 将坐标系右移2.1f glBindTexture(GL_TEXTURE_2D, texture[9]); // 天王星纹理 // 将坐标系绕Z轴旋转fUranusSpin角度,控制天王星自转 glRotatef(fUranusSpin , 0.0f, 0.0f, 1.0f); gluSphere(quadric, 0.1f, 32, 32); // 天王星球体 glPopMatrix (); glBegin(GL_LINE_LOOP); for(angle=0;angle<=360;angle++) glVertex3f(2.1f*sin(DEG_TO_RAD*angle),0,2.1f*cos(DEG_TO_RAD*angle)); glEnd(); /**********************************绘制海王星**********************************************/ glDisable(GL_LIGHT0); glEnable(GL_TEXTURE_2D ); // 开启纹理 glPushMatrix (); // 当前模型视图矩阵入栈 // 将坐标系绕Y轴旋转fNeptuneOrbit角度,控制海王星公转 glRotatef(fNeptuneOrbit , 0.0f, 1.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕X轴旋转-90度 glTranslatef(2.3f, 0.0f, 0.0f); // 将坐标系右移2.3f glBindTexture(GL_TEXTURE_2D, texture[10]); // 海王星纹理 // 将坐标系绕Z轴旋转fNeptuneSpin角度,控制海王星自转 glRotatef(fNeptuneSpin , 0.0f, 0.0f, 1.0f); gluSphere(quadric, 0.08f, 32, 32); // 海王星球体 glPopMatrix (); glBegin(GL_LINE_LOOP); for(angle=0;angle<=360;angle++) glVertex3f(2.3f*sin(DEG_TO_RAD*angle),0,2.3f*cos(DEG_TO_RAD*angle)); glEnd(); /**********************************绘制月亮************************************************/ glDisable(GL_LIGHT0); glEnable(GL_TEXTURE_2D ); // glBindTexture(GL_TEXTURE_2D, texture[11]); // 月亮纹理 glPushMatrix (); // 将坐标系绕Y轴旋转fEarthOrbit角度,控制月亮跟随地球 glRotatef(fEarthOrbit , 0.0f, 1.0f, 0.0f); glTranslatef(1.1f, 0.0f, 0.0f); // 将坐标系右移1.1f // 将坐标系绕Y轴旋转fMoonOrbit角度,控制月亮公转 glRotatef(fMoonOrbit , 0.0f, 1.0f, 0.0f); glTranslatef(0.15f, 0.0f, 0.0f); // 将坐标系绕Y轴旋转fMoonSpin角度,控制月亮自转 glBindTexture(GL_TEXTURE_2D, texture[11]); glRotatef(fMoonSpin , 0.0f, 1.0f, 0.0f); gluSphere(quadric, 0.02, 32, 32); // 月亮球体 glPopMatrix (); // 控制各星球转动的速度 if( g_bOrbitOn == true ) { fSunSpin -= g_fSpeedmodifier * (g_fElpasedTime * 10.0f); fMercuSpin -= g_fSpeedmodifier * (g_fElpasedTime * 15.0f); fMercuOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 40.0f); fVenusSpin -= g_fSpeedmodifier * (g_fElpasedTime * 10.0f); fVenusOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 30.0f); fEarthSpin -= g_fSpeedmodifier * (g_fElpasedTime * 100.0f); fEarthOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 20.0f); fMarsSpin -= g_fSpeedmodifier * (g_fElpasedTime * 30.0f); fMarsOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 50.0f); fJupiterSpin -= g_fSpeedmodifier * (g_fElpasedTime * 90.0f); fJupiterOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 35.0f); fSaturnSpin -= g_fSpeedmodifier * (g_fElpasedTime * 90.0f); fSaturnOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 25.0f); fUranusSpin -= g_fSpeedmodifier * (g_fElpasedTime * 70.0f); fUranusOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 15.0f); fNeptuneSpin -= g_fSpeedmodifier * (g_fElpasedTime * 40.0f); fNeptuneOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 5.0f); fMoonSpin -= g_fSpeedmodifier * (g_fElpasedTime * 50.0f); fMoonOrbit -= g_fSpeedmodifier * (g_fElpasedTime * 200.0f); } angle_Z += 0.01f; // 星空旋转 glutSwapBuffers(); // 交换双缓存 glFlush(); } void Reshape(int width, int height) { if (height==0) height=1; // 改变窗口 glViewport(0,0,width,height); // 设置视口 // 设置投影矩阵 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(viewer[0],viewer[1],viewer[2],viewer[3],viewer[4],-5,0,1,0); } void keyboard(unsigned char key, int x, int y) { switch(key) { case 'r': case 'R': // 视点上下左右移动 if(viewer[0]=-6.0) viewer[0]-=0.5; break; case 'u': case 'U': if(viewer[1]=-6.0) viewer[1]-=0.1; break; case'+': case '=': // 加速,减速,暂停 g_fSpeedmodifier+=1.0f; glutPostRedisplay(); break; case ' ': g_bOrbitOn = !g_bOrbitOn; glutPostRedisplay(); break; case'-': //按'-'减小运行速度 g_fSpeedmodifier-=1.0f; glutPostRedisplay(); break; case VK_ESCAPE: // 按ESC键时退出 exit(0); break; default: break; } } void special_keys(int s_keys, int x, int y) { switch(s_keys) { case GLUT_KEY_F1: // 按F1键时切换窗口/全屏模式 if(isFullScreen) { glutReshapeWindow(WIN_WIDTH, WIN_HEIGHT); glutPositionWindow(30, 30); isFullScreen = FALSE; } else { glutFullScreen(); isFullScreen = TRUE; } break; case GLUT_KEY_RIGHT: // 视角上下左右旋转 if(viewer[3]=-3.0) viewer[3]-=0.1; break; case GLUT_KEY_UP: if(viewer[4]=-4.5) viewer[4]-=0.1; break; default: break; } } void mouse(int btn, int state, int x, int y) // 远近视角 { if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) viewer[2]+=0.3; if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN&&viewer;[2]>=-3.9) viewer[2]-=0.3; } void LoadBmp(char *filename, TEXTUREIMAGE *textureImg) // 载入图片 { int i, j; FILE *file; BMPFILEHEADER bmpFile; BMPINFOHEADER bmpInfo; int pixel_size; // 初始化纹理数据 textureImg->imgWidth = 0; textureImg->imgHeight = 0; if (textureImg->data != NULL) { delete []textureImg->data; } // 打开文件 file = fopen(filename, "rb"); if (file == NULL) { return; } // 获取文件头 rewind(file); fread(&bmpFile;, sizeof(BMPFILEHEADER), 1, file); fread(&bmpInfo;, sizeof(BMPINFOHEADER), 1, file); // 验证文件类型 if (bmpFile.bfType != 0x4D42) { return; } // 获取图像色彩数 pixel_size = bmpInfo.biBitCount >> 3; // 读取文件数据 textureImg->data = new unsigned char[bmpInfo.biWidth * bmpInfo.biHeight * pixel_size]; for(i = 0 ; i < bmpInfo.biHeight; i++) { fseek(file, bmpFile.bfOffBits + (bmpInfo.biHeight - i - 1) * bmpInfo.biWidth * pixel_size, SEEK_SET); for (j = 0; j data + (i * bmpInfo.biWidth + j) * pixel_size + 2, sizeof(unsigned char), 1, file); // 绿色分量 fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 1, sizeof(unsigned char), 1, file); // 蓝色分量 fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 0, sizeof(unsigned char), 1, file); // Alpha分量 if (pixel_size == 4) { fread(textureImg->data + (i * bmpInfo.biWidth + j) * pixel_size + 3, sizeof(unsigned char), 1, file); } } } // 记录图像相关参数 textureImg->imgWidth = bmpInfo.biWidth; textureImg->imgHeight = bmpInfo.biHeight; textureImg->byteCount = pixel_size; fclose(file); } // 程序主函数 void main(int argc, char** argv) { //读图片 LoadBmp("Picture//Sky.bmp" , &skyImg;); LoadBmp("Picture//Sun.bmp" , &sunImg;); LoadBmp("Picture//Ray.bmp" , &rayImg;); LoadBmp("Picture//Mercu.bmp" , &mercuImg;); LoadBmp("Picture//Venus.bmp" , &venusImg;); //金星 LoadBmp("Picture//Earth.bmp" , &earthImg;); LoadBmp("Picture//Mars.bmp" , &marsImg;); //火星 LoadBmp("Picture//Jupiter.bmp" , &jupiterImg;); //木星 LoadBmp("Picture//Saturn.bmp" , &saturnImg;); //土星 LoadBmp("Picture//Uranus.bmp" , &uranusImg;); //天王星 LoadBmp("Picture//Neptune.bmp" , &neptuneImg;); //海王星 LoadBmp("Picture//Moon.bmp" , &moonImg;); glutInit(&argc;, argv); // 初始化GLUT库 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); // 初始化显示模式 glutInitWindowSize(WIN_WIDTH, WIN_HEIGHT); // 初始化窗口大小 glutInitWindowPosition(20,20); // 初始化窗口位置 GLuint window = glutCreateWindow(WIN_TITLE); // 建立窗口 InitGL(); // 初始化OpenGL glutDisplayFunc(Display); glutReshapeFunc(Reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(special_keys); glutMouseFunc(mouse); glutIdleFunc(Display); // 设置窗口空闲时的处理函数 glutMainLoop(); // 进入事件处理循环 }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值