opengl实现_太阳、地球及月亮的运动模型和小球的自由落体运动

合集下载

基于opengl的3D天体运动模型设计方案

基于opengl的3D天体运动模型设计方案

基于opengl的3D天体运动模型设计方案学生: ____???___学号: ************指导老师: ___???___一、背景简介1.1设计概述本3D建模设计运用Win32程序设计的基本原理,基于OpenGL接口函数,以Microsoft Visual Studio 2008为开发工具,以C++语言为开发语言,设计了一个星空背景下的太阳—地球—月球公转自转运动模型,模拟了太阳的光照效果,并实现了可以加速和减速地球和月球的自转、公转速度,而且还可以调整视图的远近和方位,方便各方面的观察。

1.2 OpenGL的基本特点OpenGL即开放图形库(Open Graphics Library),是一个三维的计算机图形和模型库。

OpenGL作为一个性能优越的图形应用程序设计接口,适用于广泛的计算机环境。

从个人计算机到工作站和超级计算机,OpenGL都能实现高性能的三维图形功能。

OpenGL是一个与硬件图形发生器的软件接口,它包括了100多个图形操作函数,开发者可以利用这些函数来构造景物模型、进行三维图形交互软件的开发。

正如上一章所述,OpenGL是一个高性能的图形开发软件包。

OpenGL支持网络,在网络系统中用户可以在不同的图形终端上运行程序显示图形。

OpenGL作为一个与硬件独立的图形接口,它不提供与硬件密切相关的设备操作函数,同时,它也不提供描述类似于飞机、汽车、分子形状等复杂形体的图形操作函数。

用户必须从点、线、面等最基本的图形单元开始构造自己的三维模型。

当然,像OpenInventor那样更高一级的基于OpenGL的三维图形建模开发软件包将提供方便的工具。

因此OpenGL的图形操作函数十分基本、灵活。

它具有如下特点。

(1)图形质量好、性能高。

无论是三维动画、CAD,还是视觉模拟、可视化计算等,都利用了OpenGL高图形质量、高性能的特点。

这个特点使得程序开发者在广播、CAD/CAM/CAE、娱乐、医学图像和虚拟现实等领域中创造和显示出难以想象的2D和3D图形。

使用opengl程序实现星球环绕

使用opengl程序实现星球环绕

GIS专业实验报告(计算机图形学)实验8 使用opengl程序实现三维星球环绕效果一.实验目的及要求使用opengl程序实现三维星球环绕效果。

二.理论基础三维图形变换:三维图形变换包括三维几何变换和投影变换,通过它可由简单图形得到复杂图形,可以用二维图形表示三维对象。

三.算法设计与分析程序源码如下:#include <gl/gl.h>#include <gl/glu.h>#include <gl/glut.h>static GLfloat angle = 0.0, moon_angle = 0.0;void display(){glClearColor( 1.0, 1.0, 0.0, 0.0 );glShadeModel( GL_SMOOTH );glMatrixMode( GL_PROJECTION );glLoadIdentity();gluPerspective( 80.0, 1.0, 1.0, 50.0 );glMatrixMode( GL_MODELVIEW );glLoadIdentity();gluLookAt(8.0, 5.0, 8.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );//定义太阳的光照//发出白色的光{GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };GLfloat light_position[] = { 0.0, 0.0, 0.5, 1.0 };//最后一个参数为正数,表明是位置性光源glEnable( GL_LIGHT0 );glEnable( GL_LIGHTING );glEnable( GL_DEPTH_TEST );//定义太阳的材质//显红色GLfloat mat_ambient[] = { 0.3, 0.0, 0.0, 1.0 };GLfloat mat_emission[] = { 0.3, 0.0, 0.0, 1.0 };//绘制太阳glLightfv( GL_LIGHT0, GL_AMBIENT, light_ambient );glLightfv( GL_LIGHT0, GL_DIFFUSE, light_diffuse );glLightfv( GL_LIGHT0, GL_SPECULAR, light_specular );glLightfv( GL_LIGHT0 ,GL_POSITION, light_position );glMaterialfv( GL_FRONT ,GL_AMBIENT_AND_DIFFUSE, mat_ambient );glMaterialfv( GL_FRONT, GL_EMISSION, mat_emission );GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 };glLightModelfv( GL_AMBIENT, ambient );glutSolidSphere( 2.0, 40, 40 );}//定制地球不发光,有材质{GLfloat mat_ambient[] = { 0.0, 0.0, 0.5, 1.0 };GLfloat mat_specular[] = { 0.0, 0.0, 1.0, 1.0 };GLfloat mat_shiness[] = { 30.0 };GLfloat mat_emission[] = { 0.0, 0.0, 0.1, 1.0 };glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_ambient );glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular );glMaterialfv( GL_FRONT, GL_EMISSION, mat_emission );glMaterialfv( GL_FRONT, GL_SHININESS, mat_shiness );glRotatef( angle, 0.0, 1.0, 0.0 );glTranslatef( 6.0, 0.0, 0.0 );glutSolidSphere( 0.5, 40, 40 );}//定制月球{GLfloat mat_ambient[] = { 0.2, 0.2, 0.2, 1.0 };GLfloat mat_specular[] = { 0.8, 0.8, 0.80, 1.0 };GLfloat mat_shiness[] = { 30.0 };GLfloat mat_emission[] = { 0.3, 0.3, 0.3, 1.0 };glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_ambient );glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular );glMaterialfv( GL_FRONT, GL_EMISSION, mat_emission );glMaterialfv( GL_FRONT, GL_SHININESS, mat_shiness );glRotatef( moon_angle, 0.0, angle, 1.0 );glTranslatef( 1.0, 0.0, 0.0 );glutSolidSphere( 0.3, 30, 30 );}glutSwapBuffers();}void idle(){angle += 0.5;moon_angle += 2.0;if ( angle > 360.0 ){angle = 0.0f;}if ( moon_angle > 360.0 ){moon_angle = 0.0;}glutPostRedisplay();}void menu( int id ){if ( id == 1 ){exit( 0 );}}int main( int argc, char ** argv ){glutInit( &argc, argv );glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE ); glutInitWindowPosition( 100, 100 );glutInitWindowSize(800, 450 );glutCreateWindow("模拟星球");glutDisplayFunc( display );glutIdleFunc( idle );glutCreateMenu( menu );glutAddMenuEntry( "Out", 1 );glutAttachMenu( GLUT_RIGHT_BUTTON );glutMainLoop();}四.程序调试及运行结果的自我分析与自我评价运行结果见下图1。

利用OpenGL绘制三维地球模型

利用OpenGL绘制三维地球模型

并指定 球体上点 的法线 向量和纹理 坐标 的方 法来实 现 。采 用 本方法 可以建立 一定半径 、经纬细分 程序可 控 以及 纹理 映射
关系稳定的球体模 型。 地球 是个 椭球体 ,且球 面上海拔 高度分 布不均 ,在设 计 球体 时 ,可首 先将地球想 像成一个 规则球形 ,对 于球面 上任 意一点 ,将地球球 面半径 与该 点对应 高程数 据相加 ,即可得 到该 点距 球心 的距离 ,通 过对球面 上点 的建 模 .可 以得 到具 有真实感 的地球 三维球 面 .叠加全球 遥感影像 数据 形成球 面 纹理 ,从而实现地球仪 的效果 。 球是 曲面 ,按有 限单元 化的思 想 将其进 行 曲 面小片 化 。 地理位 置通过经 纬线来标 定 .经线 和纬线 的交点就 是相应 的 几何 顶点 。顶 点之 间相连 接 ,可 以将 球 削出一 个 正 n面 体 , 对于正 n面体 中的每个三 角形 ,计算 每条边 的 中点 ,中点和 中点 进行连线 。这样一个 三角形小 面就用 4个小 的三角 形来 代替 。最后 把新 生成 的顶 点坐标 所表 示 的向量 进行 单位 化 , 并将此 向量乘上地球 球心距顶 点的距离 ( 即球 面半 径 R与该
Ke y wo r d s : Op e n GL g r a p h i c s l i b r a r y: 3 D Wo r l d Ma p; L OD t e c h n o l o g y
地球模 型的三维 可视化在 G o o g l e e a r t h 、Wo r l d Wi n d等商 业 软件 中已有 所 体 现 ,但 其核 心 算 法 鲜有 系统 研 究 , G o o g l e E a r t h以三 维地球 的形 式把大 量卫 星图片 、航拍 照片和

opengl实现太阳系天体运动

opengl实现太阳系天体运动

Opengl实现太阳系天体运动本文主要讲OpenGL中的几何变换。

我们生活在一个三维的世界——如果要观察一个物体,我们可以:1、从不同的位置去观察它。

(视点变换/视图变换,gluLookAt)2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它。

(模型变换)3、如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视效果。

另外,我们可能只希望看到物体的一部分,而不是全部(剪裁)。

(投影变换)4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部。

(视口变换)这些,都可以在OpenGL中实现。

1、模型变换和视图变换从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。

在OpenGL中,实现这两种功能甚至使用的是同样的函数。

由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。

设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:glMatrixMode(GL_MODELVIEW);通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。

这也只需要一行代码:glLoadIdentity();然后,就可以进行模型变换和视图变换了。

进行模型和视图变换,主要涉及到三个函数:glTranslate*,把当前矩阵和一个表示移动物体的矩阵相乘。

三个参数分别表示了在三个坐标上的位移值。

glRotate*,把当前矩阵和一个表示旋转物体的矩阵相乘。

物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数angle表示旋转的角度。

glScale*,把当前矩阵和一个表示缩放物体的矩阵相乘。

x,y,z分别表示在该方向上的缩放比例。

注意我都是说“与XX相乘”,而不是直接说“这个函数就是旋转”或者“这个函数就是移动”,这是有原因的,马上就会讲到。

假设当前矩阵为单位矩阵,然后先乘以一个表示旋转的矩阵R,再乘以一个表示移动的矩阵T,最后得到的矩阵再乘上每一个顶点的坐标矩阵v。

opengl实验四太阳系讲解

opengl实验四太阳系讲解

学院专业班学号姓名:教师评定:#include <stdlib.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h>#include <math.h>#pragma comment(lib,glaux.lib) //将glaux.lib连接到工程enum //枚举鼠标变量{BUTTON_LEFT ,//鼠标左键};int mButton = -1;int mOldY, mOldX;float z=0,c=0;float eye[3] = {0.0f, 0.0f, 2.0f}; //观察视角float rot[3] = {45.0f, 45.0f, 0.0f}; //旋转变量const int GL_WIN_WIDTH = 800; //窗口大小const int GL_WIN_HEIGHT = 600;const int GL_WIN_INITIAL_X = 0;const int GL_WIN_INITIAL_Y = 0;const int n = 1000,m=20;const float R = 1.2f,r=0.15f;//半径const float Pi = 3.1415926536f;GLuint g_TexturesArray[7];//纹理指针int iMode=1;void ProcessMenu(int value)//弹出处理函数{iMode=value;glutPostRedisplay();//强制刷新显示}void CreatePopMenu()//生成弹出式菜单函数int nMainMenu;//主菜单变量生成一个主菜单并指定菜单nMainMenu=glutCreateMenu(ProcessMenu);// 处理函数汧瑵摁?湥?瑮祲尨填充,1);//添加一个主菜单汧瑵摁?湥?瑮祲尨轮廓,2);//添加一个主菜单glutAttachMenu(GLUT_RIGHT_BUTTON);//指定激活菜单的鼠标右键}bool LoadBMP(char *filename, GLuint &texture) //调贴图大小为2的幂{AUX_RGBImageRec *pImage = NULL;pImage = auxDIBImageLoad(filename); // 装入位图if(pImage == NULL) return false; // 位图没装入返回错误glGenTextures(1, &texture); // 生成贴图(纹理)glBindTexture (GL_TEXTURE_2D,texture);// 捆绑贴图(纹理) gluBuild2DMipmaps(GL_TEXTURE_2D,4, //建立图形pImage->sizeX, // 图形宽pImage->sizeXpImage->sizeY, // 图形高pImage->sizeY,GL_RGB, GL_UNSIGNED_BYTE,pImage->data // 图形数据);free(pImage->data); // 释放位图数据占据的内存资源free(pImage);return true; // 返回成功}void Init(){glEnable(GL_DEPTH_TEST); //开启深度缓冲glClearColor(0.0,0.0,0.0,1.0);glEnable(GL_TEXTURE_2D); //启用二维文理//----------------载入图片--------------LoadBMP(data/11.bmp,g_TexturesArray[0]);LoadBMP(data/12.bmp,g_TexturesArray[1]);LoadBMP(data/13.bmp,g_TexturesArray[2]);LoadBMP(data/14.bmp,g_TexturesArray[3]);LoadBMP(data/15.bmp,g_TexturesArray[4]);LoadBMP(data/16.bmp,g_TexturesArray[5]);LoadBMP(data/17.bmp,g_TexturesArray[6]);}void glutResize(int width, int height)//重置OpenGL窗口大小{glViewport(0, 0, width, height); //重置当前视口glMatrixMode(GL_PROJECTION); //选择投影矩阵glLoadIdentity(); //重置投影矩阵gluPerspective(45.0, (float)width/(float)height, 1.0, 300.0);//设置视口大小}void glutDisplay(void) //显示函数{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);//表示物体的前向和后向面用填充面显示glPushMatrix(); //入栈glTranslatef (-eye[0], -eye[1], -10); //视口glBindTexture(GL_TEXTURE_2D, g_TexturesArray[0]);//----------------背景------------glBegin(GL_QUADS);glTexCoord2f(1.0f, 0.0f); glVertex3f(8,-8,0);glTexCoord2f(1.0f, 1.0f); glVertex3f(8,8,0);glTexCoord2f(0.0f, 1.0f); glVertex3f(-8,8,0);glTexCoord2f(0.0f, 0.0f); glVertex3f(-8,-8,0);glEnd();glPopMatrix(); //出栈glPushMatrix(); //入栈glTranslatef (-eye[0], -eye[1], -eye[2]);glRotatef(rot[0], 1.0f, 0.0f, 0.0f);glRotatef(rot[1], 0.0f, 1.0f, 0.0f);glRotatef(rot[2], 0.0f, 0.0f, 1.0f);//---------------太阳--------------if(iMode==1){GLUquadricObj * quadric1; //建立一个曲面对象指针quadric1 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric1,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric1,GLU_FILL); //用面填充绘制场景glBindTexture(GL_TEXTURE_2D, g_TexturesArray[1]);//绑定纹理gluSphere(quadric1,0.3f,64,64);//画一个填充太阳}else if(iMode==2){glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);画一个线条太阳glutWireSphere(0.3f,32,32);//glEnable(GL_TEXTURE_2D);//启用纹理}//-----------土星公转轨道------------glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glBegin(GL_LINE_LOOP);for(int j=0; j<n; j++)glVertex3f(R*cos(2*Pi/n*j),0,R*sin(2*Pi/n*j));glEnd();glEnable(GL_TEXTURE_2D);//启用纹理//-----------地球公转轨道---------------glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glBegin(GL_LINE_LOOP);for(j=0; j<n; j++)glVertex3f(0.7*cos(2*Pi/n*j),0,0.7*sin(2*Pi/n*j));glEnd();glEnable(GL_TEXTURE_2D);//启用纹理//------------------土星---------------------------glPushMatrix();//入栈glRotatef(z, 0.0f, 1.0f, 0.0f);glTranslatef (1.2, 0, 0);glPushMatrix(); //入栈glRotatef(c, 0.0f, 1.0f, 0.0f);glRotatef(90, 1.0f, 0.0f, 0.0f);if(iMode==1){GLUquadricObj * quadric2; ////建立一个曲面对象指针quadric2 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric2,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric2,GLU_FILL); //用面填充绘制场景glBindTexture(GL_TEXTURE_2D, g_TexturesArray[2]);//绑定纹理gluSphere(quadric2,0.12f,64,64);//画一个填充土星}else if(iMode==2){glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glutWireSphere(0.12f,25,25);//画一个线条土星glEnable(GL_TEXTURE_2D);//启用纹理}glPopMatrix(); //出栈//---------------土星一号卫星-----------------入栈glPushMatrix();//glRotatef(c, 0.0f, 0.0f, 1.0f);glTranslatef (0.25, 0, 0);if(iMode==1){GLUquadricObj * quadric3; ////建立一个曲面对象指针quadric3 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric3,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric3,GLU_FILL); //用面填充绘制场景glBindTexture(GL_TEXTURE_2D, g_TexturesArray[3]);//绑定纹理gluSphere(quadric3,0.03f,64,64);//画一个填充卫星}else if(iMode==2){glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glutWireSphere(0.03f,25,25);//画一个线条卫星glEnable(GL_TEXTURE_2D);//启用纹理}glPopMatrix();//出栈//-----------------土星一号卫星轨道--------------glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glBegin(GL_LINE_LOOP);for(j=0; j<n; j++)glVertex3f(0.25*cos(2*Pi/n*j),0.25*sin(2*Pi/n*j),0);glEnd();glEnable(GL_TEXTURE_2D); //启用纹理//------------------土星二号卫星--------------------glPushMatrix(); //入栈glRotatef(c, 1.0f, 0.0f, 0.0f);glTranslatef (0, 0, 0.25);if(iMode==1){GLUquadricObj * quadric4; ////建立一个曲面对象指针quadric4 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric4,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric4,GLU_FILL); //用面填充绘制场景glBindTexture(GL_TEXTURE_2D, g_TexturesArray[4]);//绑定纹理gluSphere(quadric4,0.03f,64,64);//画一个填充卫星}else if(iMode==2){glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glutWireSphere(0.03f,25,25);//画一个线条卫星glEnable(GL_TEXTURE_2D);//启用纹理}glPopMatrix();//出栈//----------------土星二号卫星轨道-------------------glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glBegin(GL_LINE_LOOP);for(j=0; j<n; j++)glVertex3f(0,0.25*cos(2*Pi/n*j),0.25*sin(2*Pi/n*j));glEnd();glEnable(GL_TEXTURE_2D);//启用纹理//------------------土星的行星环--------------glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);for(int i=0; i<m; i++){ glBegin(GL_LINE_LOOP);for(int j=0; j<n; j++)glVertex3f((r+i*0.004)*cos(2*Pi/n*j),0,(r+i*0.004)*sin(2*Pi/n*j));glEnd(); }glEnable(GL_TEXTURE_2D); //启用纹理glPopMatrix();//出栈//------------------地球-------------------glPushMatrix();//入栈glRotatef(z*2, 0.0f, 1.0f, 0.0f);glTranslatef (0, 0, 0.7);glPushMatrix(); //入栈glRotatef(c, 0.0f, 1.0f, 0.0f);glRotatef(-90, 1.0f, 0.0f, 0.0f);if(iMode==1){GLUquadricObj * quadric5; ////建立一个曲面对象指针quadric5 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric5,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric5,GLU_FILL); //用面填充绘制场景glBindTexture(GL_TEXTURE_2D, g_TexturesArray[5]);//绑定纹理gluSphere(quadric5,0.1f,64,64);//画一个填充地球}else if(iMode==2){glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glutWireSphere(0.1f,25,25);//画一个线条地球启用纹理glEnable(GL_TEXTURE_2D);//}glPopMatrix(); //出栈//-----------------月亮--------------glPushMatrix();//入栈glRotatef(c, 1.0f, 0.0f, 0.0f);glTranslatef (0, 0, 0.15);if(iMode==1){GLUquadricObj * quadric6; ////建立一个曲面对象指针quadric6 = gluNewQuadric(); //建立一个曲面对象指针gluQuadricTexture(quadric6,GLU_TRUE); //建立纹理坐标gluQuadricDrawStyle(quadric6,GLU_FILL); //用面填充绘制场景glBindTexture(GL_TEXTURE_2D, g_TexturesArray[6]);//绑定纹理gluSphere(quadric6,0.025f,64,64);//画一个填充月亮}else if(iMode==2){glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glutWireSphere(0.025f,25,25);//画一个线条月亮glEnable(GL_TEXTURE_2D);//启用纹理}glPopMatrix();//出栈//-----------------月亮轨道---------------glDisable(GL_TEXTURE_2D);//取消纹理glColor3f(1.0,1.0,1.0);glBegin(GL_LINE_LOOP);for(j=0; j<n; j++)glVertex3f(0,0.15*cos(2*Pi/n*j),0.15*sin(2*Pi/n*j));glEnd();glEnable(GL_TEXTURE_2D); //启用纹理glPopMatrix();//出栈z+=0.05;c+=0.3;glPopMatrix();//出栈glFlush();glutSwapBuffers();}void clamp(float *v){int i;图像旋转一周后回到原地// for (i = 0; i < 3; i ++)if (v[i] > 360 || v[i] < -360)v[i] = 0;}void glutMotion(int x, int y) //图像移动函数{if (mButton == BUTTON_LEFT) //按下左键时可以任意旋转图像{rot[0] -= (mOldY - y);rot[1] -= (mOldX - x);clamp (rot);}mOldX = x;mOldY = y;}void glutMouse(int button, int state, int x, int y)//鼠标控制函数{if(state == GLUT_DOWN){mOldX = x;mOldY = y;mButton = BUTTON_LEFT;} else if (state == GLUT_UP)mButton = -1;}void glutKeyboard(unsigned char key, int x, int y) //键盘控制函数{switch (key){case 's': //按S键放大图像case 'S':eye[2] -= 0.05;break;case 'W': //按W键缩小图像case 'w':eye[2] += 0.05;break;}}int main(int argc, char** argv) //主函数{glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA); glutInitWindowPosition( GL_WIN_INITIAL_X, GL_WIN_INITIAL_Y ); glutInitWindowSize( GL_WIN_WIDTH, GL_WIN_HEIGHT );glutInit( &argc, argv );汧瑵牃慥整楗摮睯尨太阳系);glutDisplayFunc(glutDisplay);glutIdleFunc(glutDisplay);glutReshapeFunc(glutResize);Init();glutMouseFunc(glutMouse);glutMotionFunc(glutMotion);glutKeyboardFunc(glutKeyboard);CreatePopMenu();glutMainLoop();return 0;}。

计算机图形学课程设计完本

计算机图形学课程设计完本

1中文摘要本次课程设计采用OpenGL来完成。

OpenGL是个定义了一个跨编程语言、跨平台的编程接口的规格,它用于三维图象(二维的亦可)。

OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。

本次课程设计是在win7系统下VC++6.0中的win32环境中,通过使用OpenGL所提供的标准库函数,综合图形学里的坐标转换,投影变换,光照以及纹理等知识,实现一个简单的太阳系的运行状况。

该系统仅做演示使用,将只包括太阳,地球与月亮,并且不保证相关数据的设定准确性。

目录一、课程设计任务及要求 (1)二、需求分析 (1)三、系统设计 (1)四、详细设计 (3)4.1 初始化的设定 (3)4.2 光源的位置与观察位置的设定 (4)4.3 纹理映射的设置 (5)4.4 各星球球体的绘制 (7)4.5 星球公转轨道 (9)4.6 人机交互式的实现 (10)五、运行调试与分析讨论 (12)5.1 程序运行截图 (12)5.2 结果分析 (13)六、设计体会与小结 (14)七、参考文献 (16)一、课程设计任务及要求1.利用OpenGL创建太阳,地球,月亮三个球体。

2. 实现“月亮绕着地球转,地球绕着太阳转”。

3. 为太阳,地球,月亮附上不同的纹理。

4. 具有较好的动画效果,消除闪烁现象。

5. 其他功能的添加。

二、需求分析本次课程设计使用的编译软件为Visual C++ 6.0。

设计中通过调用OpenGL函数库以来完成太阳,月亮,地球的球体绘制与纹理的加载,通过矩阵的变换以实现星球的运动效果。

从而模拟出太阳系的运行效果动画。

在之后,加入星球的轨道轨迹,使得模拟系统3D效果更加明显。

并加入人机交互操作。

通过“q,w,e,s,a,d”键来调整观察视角,可以实现全方位对此系统进行观察,使系统具有一定的可操作性。

三、系统设计本次课题为:实现太阳系运行动画。

系统设计步骤为:1.太阳,地球,月亮三个球体的创建。

OpenGL中绘制太阳,地球,月亮的运动模型

计算机图形学实验报告1、实验目的和要求利用第七章所学的知识,试在OpenGL中绘制太阳,地球,月亮的运动模型,并用相应的代码表示出来。

2、实验内容OpenGL中只提供了两种投影方式,一种是正投影,另一种是透视投影。

不管是调用哪种投影函数,为了避免不必要的变换,必须调用glMAtrixMode (GL_PROJECTION )因此在本实验中要学习这种方法,并使用投影的方式来做题。

3、实验步骤1)相关算法及原理描述为了简单起见,我们把三个天体都想象成规则的球体。

而我们所使用的glut实用工具中,正好就有一个绘制球体的现成函数:glutSolidSphere,这个函数在“原点”绘制出一个球体。

由于坐标是可以通过glTranslate*和glRotate*两个函数进行随意变换的,所以我们就可以在任意位置绘制球体了。

函数有三个参数:第一个参数表示球体的半径,后两个参数代表了“面”的数目,简单点说就是球体的精确程度,数值越大越精确,当然代价就是速度越缓慢。

这里我们只是简单的设置后两个参数为20。

太阳在坐标原点,所以不需要经过任何变换,直接绘制就可以了。

地球则要复杂一点,需要变换坐标。

由于今年已经经过的天数已知为day,则地球转过的角度为day/一年的天数*360度。

前面已经假定每年都是360天,因此地球转过的角度恰好为day。

所以可以通过下面的代码来解决:glRotatef(day, 0, 0, -1);/* 注意地球公转是“自西向东”的,因此是饶着Z轴负方向进行逆时针旋转*/ glTranslatef(地球轨道半径, 0, 0);glutSolidSphere(地球半径, 20, 20);月亮是最复杂的。

因为它不仅要绕地球转,还要随着地球绕太阳转。

但如果我们选择地球作为参考,则月亮进行的运动就是一个简单的圆周运动了。

如果我们先绘制地球,再绘制月亮,则只需要进行与地球类似的变换:glRotatef(月亮旋转的角度, 0, 0, -1);glTranslatef(月亮轨道半径, 0, 0);glutSolidSphere(月亮半径, 20, 20);但这个“月亮旋转的角度”,并不能简单的理解为day/一个月的天数30*360度。

OpenGL(七)光照模型及设置

OpenGL(七)光照模型及设置OpenGL把现实世界中的光照系统近似归为三部分,分别是光源、材质和光照环境。

光源就是光的来源,是“光”这种物质的提供者;材质是指被光源照射的物体的表⾯的反射、漫反射(OpenGL不考虑折射)特性;材质反映的是光照射到物体上后物体表现出来的对光的吸收、漫反射、反射等性能;光照环境反应环境中所有光源发出的光经过⽆数次反射、漫反射之后整体环境所表现出来的光照效果。

指定合适的光照环境参数可以使得最后形成的画⾯更接近于真实场景。

⼀、光源光照模型OpenGL中的光照模型中的反射光分为三个分量,分别是环境反射光(Ambient Light)、漫反射光(Diffuse Light)和镜⾯反射光(Specular Light)。

环境光Ambient:是由光源发出经环境多次散射⽽⽆法确定其⼊射⽅向的光,即似乎来⾃所有⽅向。

其特征是⼊射⽅向和出射⽅向均为任意⽅向。

漫射光Diffuse:来⾃特定⽅向,它垂直于物体时⽐倾斜时更明亮。

⼀旦它照射到物体上,则在各个⽅向上均匀地发散出去,效果为⽆论视点在哪⾥它都⼀样亮,其特征是⼊射⽅向唯⼀、出射⽅向为任意⽅向。

镜⾯光Specular:来⾃特定⽅向并沿另⼀⽅向反射出去,⼀个平⾏激光束在⾼质量的镜⾯上产⽣100%的镜⾯反射,其特征是⼊射⽅向和出射⽅向均唯⼀。

创建光源OpenGL中⽤函数glLightfv来创建光源,函数原型是:void glLightfv (GLenum light, GLenum pname, const GLfloat *params)第⼀个参数light指定所创建的光源号,如GL_LIGHT0、GL_LIGHT1、...、GL_LIGHT7。

第⼆个参数pname指定光源特性,这个参数的具体信息见下表所⽰。

第三个参数设置相应的光源特性值。

例如下边定义了⼀个位置在(0,0,0),没有环境光,镜⾯反射光和漫反射光都为⽩光的光源:GLfloat light_position[] = { 0.0, 0.0, 0.0, 0.0 };GLfloat light_ambient [] = { 0.0, 0.0, 0.0, 1.0 };GLfloat light_diffuse [] = { 1.0, 1.0, 1.0, 1.0 };GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };glLightfv(GL_LIGHT0, GL_POSITION, light_position);glLightfv(GL_LIGHT0, GL_AMBIENT , light_ambient );glLightfv(GL_LIGHT0, GL_DIFFUSE , light_diffuse );glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);光源的位置坐标采⽤齐次坐标(x, y, z, w)设置。

计算机图形学复习题目

第一章1.1 名词解释:图形、图像、点阵法、参数法。

1.2 图形包括哪两方面的要素?在计算机中如何表示它们?1.3 什么叫计算机图形学?分析计算机图形学、数字图像处理和计算机视觉学科间的关系。

1.4 有关计算机图形学的软件标准有哪些?1.5 试从科学发展历史的角度分析计算机图形学以及硬设备的发展过程。

1.6 试发挥你的想象力,举例说明计算机图形学有哪些应用范围,解决的问题是什么?1.7 一个交互性计算机图形系统必须具有哪几种功能?第二章2.1 名词解释:随机扫描、光栅扫描、图形显示子系统、像素点、光点、屏幕分辨率、显示分辨率、存储分辨率、组合像素法、颜色位面法、位平面、颜色查找表。

2.2 试列举出你所知道的图形输入与输出设备。

2.3 阴极射线管由哪几部分组成?它们的功能分别是什么?2.4 简述什么叫桶形失真?如何校正?2.5 简述荫罩式彩色阴极射线管的结构和工作原理。

2.6 比较荫罩式彩色阴极射线管和穿透式彩色阴极射线管的异同。

2.7 简述黑底荫罩式彩色阴极射线管的结构和特点。

2.8 简述光栅扫描图形显示器的工作逻辑。

2.9 基于光栅扫描的图形显示子系统由哪几个逻辑部件组成?它们的功能分别是什么?2.10 什么是像素点?什么是显示器的分辨率?2.11 某些显示卡为什么要采用颜色查找表?采用颜色查找表的系统的工作原理是什么?2.12 确定用你的系统中的视频显示器x和y方向的分辨率,确定其纵横比,并说明你的系统怎样保持图形对象的相对比例。

2.13 如何根据显示器的指标计算显示存储器的容量。

2.14 图形的硬拷贝设备有哪些,简述其各自的特点。

第三章3.1 名词解释(可用图示):回显、约束、网格、引力域、橡皮筋技术、草拟技术、拖动、旋转、形变。

3.2 什么是用户模型,设计一个好的用户接口要涉及到哪些因素?3.3 gks的有哪六种逻辑输入设备,试评价这六种逻辑分类方法。

3.4 举例说明什么是请求方式、取样方式、事件方式及其组合形式。

OpenGL图形编程1介绍(陈永强)


18
1.1OpenGL的主要功能
位图和图像处理
OpenGL 还提供了专门对位图和图象进行操作的 函数。
19
1.1OpenGL的主要功能
纹理映射
三维景物因缺少景物的具体细节而显得不够真实,为了更 加逼真地表现三维景物,OpenGL 提供了纹理映射的 功能。OpenGL 提供的一系列纹理映射函数使得开发 者可以十分方便地把真实图象贴到景物的多边形上,
32位整数 32位浮点数 64位浮点数
short
long float double
S
L F D
GLubyte,GLboolean
GLshort GLuint,GLenum,GLbitfield
位图字体以及把文本放在窗口的某一位置等这些函数把
Windows 和 OpenGL 揉合在一起。
34
1.4OpenGL基本语法
组成
Win32 API 函数库
这部分函数没有专用的前缀,主要用于处理像素 存储格式和双帧缓存。
35
1.4OpenGL基本语法
函数命名规则
OpenGL函数都遵循一个命名约定,即采用以下格
从而可以在视窗内绘制逼真的三维景观。
20
1.1OpenGL的主要功能
实时动画
为了获得平滑的动画效果,需要先在内存中生成 下一幅图象,然后把已经生成的图象从内存拷 贝到屏幕上,这就是 OpenGL 的双缓存技术 (double buffer)。OpenGL 提供了双缓存 技术的一系列函数。
21
1.1OpenGL的主要功能
交互技术
目前有许多图形应用需要人机交互,OpenGL 提
供了方便的三维图形人机交互接口,用户可以选
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验六1、实验目的和要求了解且掌握OpenGL中包含的有关三维变换的操作,并且做出模型视图变换、投影变换和视见区变换的实例。

2、实验内容1)在OpenGL中绘制太阳、地球和月亮的运动模型。

2)在OpenGL中创建一个球体动画,使球体在窗口内做自由落体运动,并在撞击地面(窗口的下边界)后能够弹回原来的高度。

3、实验步骤1)相关算法及原理描述①矩阵堆栈在计算机图形学中,所有的变换都是通过矩阵乘法来实现的,即将三维形体顶点构成的齐次坐标矩阵乘以三维变换矩阵就得到变换后的形体顶点的其次坐标矩阵,这样只要求出形体三维变换矩阵,就可以得到变换后的形体。

在OpenGL中,对象的变换也是通过矩阵来实现的。

在进行矩阵操作前,需要指定当前操作的矩阵对象,可以使用函数glMatrixMode(GLenum mode); 定义。

矩阵堆栈主要用来保存和恢复矩阵的状态,主要用于具有层次结构的模型绘制中,以提高绘图效率。

利用函数voidglPushMatrix(void);Void glPopMatrix(void); 实现矩阵堆栈的操作。

矩阵堆栈是有深度的,如果超出了堆栈深度或当堆栈为空时试图弹出栈顶矩阵,都会发生错误。

可以用下面函数获得堆栈深度的最大值: glGet(GL_MAX_MODELVIEW_STACK_DEPTH);glGet(GL_MAX_PROJECTION_STACK_DEPTH);②模型视图变换模型视图矩阵是一个4*4的矩阵,用于指定场景的视图变换和几何变换。

在进行模型视图矩阵操作前,必须调用函数glMatrixMode(GL_MODELVIEW)指定变换只能影响模型试图矩阵。

主要有以下两种方法。

1.2.1、直接定义矩阵利用函数 void glLoadMartrix{fd}(const TYPE *m);将m 所指定的矩阵置为当前矩阵堆栈的栈顶矩阵。

1.2.2、利用高级矩阵函数平移矩阵函数:void glTranslate{df}(TYPE x,TYPE y,TYPE z);用当前矩阵乘以平移矩阵。

旋转矩阵函数void glRotate{df}(TYPE angle,TYPE x,TYPW y,TYPE z);缩放矩阵函数void glScale{df}(TYPE x,TYPE y,TYPE z);如不需要效果积累可调用重置矩阵函数void glLoadIdentity(void); 该函数将单位矩阵置为当前变换矩阵。

③投影变换有两种投影方式,不管调用哪种,必须调用glMAtrixMode(GL_PROJECTION);指定当前处理的矩阵是投影变换矩阵。

1.3.1、正投影它的有限观察空间是一个长方体,无论物体距离相机多远,投影后的物体大小尺寸不变。

正投影函数有两个:void glOrtho(GLdouble left,GLdouble right,GLdouble botton,GLdouble top,GLdouble near,GLdouble far);void gluOrtho2D(GLdouble left,GLdouble right,GLdoubl botton, GLdouble top);1.3.2、透视投影特点是距离视点近的物体大,距离视点远的物体小,远到极点即为消失。

透视投影函数也有两个:void glFrustum(GLdouble left,GLdouble Right,GLdouble botton, GLdouble top,GLdouble near,GLdouble far);void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar);2)程序调试、测试与运行结果分析①太阳、地球和月亮的运动模型②小球的自由落体运动4、附录(1)太阳、地球和月亮的运动模型#include <gl/glut.h>static int day = 200;void display(){glEnable(GL_DEPTH_TEST);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(75,1,1,400000);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0,-200000,200000, 0,0,0, 0,0,1);glColor3f(1,0,0);//sunglutSolidSphere(69600,20,20);glColor3f(0,0,1);glRotatef(day,0,0,-1);glTranslatef(150000,0,0);//earthglutSolidSphere(15945,20,20);glColor3f(1,1,0);glRotatef(day/30.0*360 - day, 0,0,-1);glTranslatef(38000,0,0);//moonglutSolidSphere(4345,20,20);glutSwapBuffers();}void timer(int p){ day ++;if(day >360)day = 0;glutTimerFunc(50,timer,0);glutPostRedisplay();}int main(int argc,char **argv){ glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutCreateWindow("earth,moon,sun");glutInitWindowSize(400,400);glutDisplayFunc(display);glutTimerFunc(50,timer,0);glutMainLoop();return 0;}(2)小球的自由落体运动#include<GL/glut.h>#include<stdlib.h>#include<stdio.h>#include<time.h>#include<math.h>#define PI 3.1415926double move=20.0;int i=0;int down=1;int count=1;double timeSpan=0; //下降到底所需时间double movey=0.0;double duration=0.0; //持续时间double length=0.0;clock_t start,end;void init(void){ printf(" init");GLfloat mat_specular[]={220.220,220.0,220.0,220.0};GLfloat mat_shininess[]={70.0};GLfloat light_position[]={0.0, 0.0, 0.0, -2.0}; //r-l u-d f-b GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };GLfloat diffuseLight[] = { 0.6f, 0.6f, 0.6f, 1.0f };GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};glClearColor(0.3,0.8,0.8,0.0); //bgcglColor3ub(23, 17, 215);glShadeModel(GL_SMOOTH);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);glLightfv(GL_LIGHT0,GL_SPECULAR,specular);glLightfv(GL_LIGHT0,GL_POSITION,light_position);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glEnable(GL_DEPTH_TEST); //启用深度测试}void reshape(int w,int h){ printf(" reshape");glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if(w<=h)glOrtho(-12,12,-12*(GLfloat)(h)/(GLfloat)(w),12*(GLfloat)(h)/(GLfloat )(w), -1.0,1.0);elseglOrtho(-12*(GLfloat)(w)/(GLfloat)(h),12*(GLfloat)(w)/(GLfloat)(h),-1 2,12,-1.0,1.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void initDisplay(void){ printf(" initDisplay()");down=1; //向下运动glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(0.0,20.0,0.0);glutSolidSphere(0.4,40,50);glutSwapBuffers();}void display(void){ printf(" Display()");glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(0,move,0.0);glutSolidSphere(0.4,40,50);glutSwapBuffers();}void MoveSphereUp(){ end=clock();duration = (double)(end - start-16.0) /CLOCKS_PER_SEC;length=5*(timeSpan-duration)*(timeSpan-duration);move=20-length;if(move>19.932) {move=20;down=1;printf("%i",down);start=clock();}display();glLoadIdentity();}void MoveSphereDown(){if(count==1){start=clock();count=0;}end=clock();duration = (double)(end - start) /CLOCKS_PER_SEC;length=5*duration*duration;move=20-length;if(move<-20) {timeSpan=duration; //记下下降所经历的时间move=-20;start=clock();down=0; //向上运动}display();glLoadIdentity();}void TimerFunc2(int value){if(i==0){ //leftGLfloat light_position[]={2.0,0.0,0.0,0.0}; //r-l u-d f-bglLightfv(GL_LIGHT0,GL_POSITION,light_position);}if(i==1){ //left-upGLfloat light_position[]={2.0,2.0,0.0,0.0}; //r-l u-d f-bglLightfv(GL_LIGHT0,GL_POSITION,light_position);}if(i==2){ //upGLfloat light_position[]={0.0,2.0,0.0,0.0}; //r-l u-d f-bglLightfv(GL_LIGHT0,GL_POSITION,light_position);}if(i==3){ //up-rightGLfloat light_position[]={-2.0,2.0,0.0,0.0}; //r-l u-d f-bglLightfv(GL_LIGHT0,GL_POSITION,light_position);}if(i==4){ //rightGLfloat light_position[]={-2.0,0.0,0.0,0.0}; //r-l u-d f-bglLightfv(GL_LIGHT0,GL_POSITION,light_position);}if(i==5){ //right-downGLfloat light_position[]={-2.0,-2.0,0.0,0.0}; //r-l u-d f-bglLightfv(GL_LIGHT0,GL_POSITION,light_position);}if(i==6){ //downGLfloat light_position[]={0.0,-2.0,0.0,0.0}; //r-l u-d f-bglLightfv(GL_LIGHT0,GL_POSITION,light_position);}if(i==7){ //down-leftGLfloat light_position[]={2.0,-2.0,0.0,0.0}; //r-l u-d f-bglLightfv(GL_LIGHT0,GL_POSITION,light_position);}i=(++i)%8;printf("%i",i);glutTimerFunc(60,TimerFunc2,1);}void TimerFunc1(int value){if(down==1){MoveSphereDown();}if(down==0){MoveSphereUp();}glutTimerFunc(10,TimerFunc1,0);}int main(int argc,char *argv[]){ glutInit(&argc,argv);glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);glutInitWindowSize(400,740);glutInitWindowPosition(300,20);glutCreateWindow("小球自由落体运动");init();glutDisplayFunc(initDisplay);glutReshapeFunc(reshape);glutTimerFunc(1400,TimerFunc1,0); //毫秒glutTimerFunc(400,TimerFunc2,1); //毫秒glutMainLoop();return 0;}。

相关文档
最新文档