欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    基于opengl的三维场景漫游实现(共10页).doc

    • 资源ID:13889425       资源大小:41.50KB        全文页数:10页
    • 资源格式: DOC        下载积分:20金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要20金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    基于opengl的三维场景漫游实现(共10页).doc

    精选优质文档-倾情为你奉上基于opengl的三维场景漫游实现摘要: 本课题是关于opengl三维场景的实现,要求能够实现人机交互,具有缩放、旋转等基本的功能。利用opengl创建三维模型的原理,本课题在理解opengl创建图形元的基础上,实现了简单三维场景模型的建立。通过建立全局Camera,实现了对场景全方位的观测,同时能够及时响应键盘和鼠标的操作。在此基础上,利用天空盒子和全局地形的方法,实现了三维场景的基本框架,能够在虚拟场景中任意角度的漫游。通过纹理贴图的方法,实现场景的创建,并对场景内部的事物进行碰撞检测,来实现简单的三维场景漫游。关键词:三维建模; 全局Camera; 场景漫游; 纹理贴图; 碰撞检测目录 专心-专注-专业1 课题论述1.1选题背景简介 随着科技的发展,人们对视觉的需求也越来越高,这正好也促发了计算机图形学的快速发展:从简单的平面图形到3D空间的立体图形空间的一个转变,为opengl提供了广阔的应用和开发前景。随着opengl的越来越成熟,在各个领域的应用也变得广泛起来。从计算机、多媒体、影视到医学、工业等领域。Opengl开发的重心也有所转变,从普通的三维场景的建立,到现在的大型复杂场景的三维信息生成、实时三维场景光影效果的模拟和实时三维场景的内存使用控制,opengl的发展越来越成熟。 正是基于opengl目前广泛的应用,本课题从opengl基本的图形元的创建、渲染、视角的转换等方面,选择一些opengl的基本操作,实现简单的三维场景空间的漫游,促进对opengl进一步的了解,也为以后进一步的开发做准备。1.2系统开发平台及运行环境 本设计是基于Opengl 1.0在windows7操作系统下使用Visual C+6.0集成开发环境开发并调试,设计中使用了基于Win Application的架构。1.2.1 开发环境的搭建本设计是在Visual C+ 6.0下使用Opengl1.0库开发的,开发环境搭建步骤详细如下:(1)安装Visual C+ 6.0。(2)配置Opengl1.0由于Visual C+ 6.0本身带有安装好的opengl1.0版本,所以一些头文件和bin路径的设置就不必要做了。但自带的opengl1.0 没有包含 glut函数库,所以需要下载glut函数库,并正确的设置include和bin的路径,并把dll文件放到system32下。1.2.2 opengl绘图机制 在Windows环境的绘图机制下使用图形设备接口GDI作图要通过设备上下文调用相应的函数,用opengl作图也是这样。Opengl通过“渲染上下文”即RC完成对三维图形的绘制。Windows下的设备上下文和窗口都支持“文图格式”属性,和RC在位图结构方面是一致的。因此只要在创建RC的同时与一个DC建立联系,opengl函数就可以通过对应的DC绘制到相应的显示设备上面。2课题实现的关键技术2.1 场景建模 场景的建模能够直接的展示出场景的 三维特性,也是影响三维可视化功能的关键。在本课题中,我主要完成了一下几个场景的建模。 首先是地形的建模,在地形的建模中,采用了四边形近视模型和纹理贴图的方式来完成。在xoz平面,建立的是一个46*46的网格模型,其中每个方格的大小大约为7个坐标。在y方向,通过读取位图信息的方式,建立的随机高度的模型。其中,地形中心部分为平面,用于建立一些基本的场景,而地形的边界部分,用位图数据随机读取,生成一圈环绕的小山,把整个场景环绕在山围之中。房子模型的建立是通过opengl简单的图形元建立,首先建立房子的四周,即四个围墙,用四个平面图形建立,然后屋顶通过两个四边形和两个三角形进行建模,实现三维房屋的构建。天空的建立有很多方法,基本的有两种:一种是天空盒法,另一种是天空球法。天空盒是有一个长方体,在它的各个面上贴有天空的图片组成。天空球是有一个球体,在它的表面贴上天空的纹理组成。天空球相对于天空盒子较简单,因为它只需要一张纹理,但为了显示效果的真实性,本课题采用的是天空盒子的方法,建立六个天空的面,然后选取合适的天空图片进行贴图。由于六个面的链接处会出现一条线,为了实现天空的无缝连接,需要设置纹理的一些属性,来达到天空的无缝连接。2.2 场景渲染场景的渲染对于三维空间来说也是十分最要的,因为这直接决定着场景的真实性。本课题主要利用了纹理映射场景进行渲染。纹理映射是把纹理空间中的纹理像素映射到屏幕空间中的像素的过程,利用纹理映射,可以使三维的世界显得更加的逼真。本课题中主要对地形、天空、房子等进行了纹理的渲染,同时利用鼠标来旋转摄像机,相当于对物体进行了三维空间的旋转,来更好的观测场景的效果。2.3 纹理映射 纹理映射技术的原理是通过把纹理空间坐标与物体空间坐标的每一点建立关联,实现把二维的纹理图像映射到三维的物体表面,从而呈现出真实的视觉效果。 纹理映射操作包括启用及载入纹理,指定纹理坐标,设置纹理的参数,使用纹理对象等方面。Opengl中规定纹理贴图在RGBA模式下。本文启用了opengl中的纹理映射技术来对三维场景中的地形、天空和房子进行纹理的渲染,实现的大体过程如下:(1) 首先要创建纹理对象并且为此对像指定纹理。调用glGenTexture()函数创建纹理对象,使用一个正整数对纹理对象进行编号,并把相应的对象存储到指定的数组中。最后调用glBindTexture()函数实现把生成的纹理名字绑定到对应的目标纹理上。(2) 控制滤波的方式Opengl在图像的时候,有可能显示的图像比原始的要大,也有可能比原始的图像要小,所以要采用控制滤波的方式,对其进行适当的放大和缩小。本课题采用的是GL_LINEAR方式,这样纹理总是以平滑的方式来显示。(3) 启用纹理并载入纹理的数据首先要启用纹理,通过glEnable(GL_TEXTURE_2D)来启用二维的纹理,并通过glBindTexture()和glTexImage2D()来绑定纹理数据。由于贴纹理的时候要明确纹理与映射物体的映射关系,所以通过函数glTexCoord2f()来进行绑定。2.4 碰撞检测 碰撞检测技术主要是对场景内部的物体进行的,由于场景都是自己通过三维图形建立的,而随着在场景内部全局Camera的移动,相当于观察者在场景中进行漫游。当观察者移动到一些场景内部时,如果没有碰撞检测,就会直接穿过物体,不符合实际的情况,所以需要引入碰撞检测技术。碰撞检测技术有很多中,本课题采用的是基于盒子的碰撞检测原理,即在被检测物体的一定范围之内,假设存在一个盒子把物体包围住,当观察者移动到盒子的范围边界时,就停止一定,然后根据Camera的角度,进行偏移。本课题场景比较简单,主要是有山和房子组成,所以碰撞检测只做了山和房子的检测。对于山的检测比较简单,利用盒子原理,在山的内部边界部分,设置一个四方体边界,当相机移动到边界的时候,就停止移动,然后根据角度左右或则前后移动,防止穿过环绕山。而对于房子的检测,就要分为好几部分,墙面的检测,门的检测。其中在房子内部和外部的边界部分都要做边缘的检测,使从外部进入和里面出来都不能穿过墙面和门。其实现方法也是在墙面和门的附近很小的距离设置检测边界,当到达边界时,即碰撞到了物体,不能越过边界,从而达到碰撞检测并不穿过物体的目的。3漫游场景的实现 3.1 全局Camera的创建由于需要在虚拟场景中实现漫游,如果只是简单的控制坐标轴的旋转,不能够对场景中的物体进行全方位的观察,因此引入了全局Camera,通过键盘的方向键和鼠标的移动,来控制Camera移动的方向和角度,实现场景的漫游。场景中大量的旋转和平移,如果没有相机来控制的话,程序会显得杂乱。因此。本课题首先创建了Camera来实现对ViewMatrix矩阵和ProjectMatrix矩阵的管理。通俗的说,就是由相机来维护整个场景的平移、旋转等矩阵换算,还有远近裁剪面的矩阵,这样大量复杂计算全都在相机这样一个实体类中得以处理,使用者只需要调用相机的外部接口来满足自己的视角,相机内部处理矩阵计算,最终传递给OpenGL对应的Matrix,从而支撑起整个场景的视觉效果。在程序设计中,首先创建了Camera类,包含一些基本的处理函数,关键的函数部分如下:void setCamera(float positionX, float positionY, float positionZ, float viewX, float viewY, float viewZ, float upVectorX, float upVectorY, float upVectorZ);void rotateView(float angle, float X, float Y, float Z); /* 旋转摄像机方向 */void setViewByMouse(); /* 根据鼠标设置摄像机观察方向 */void yawCamera(float speed); /* 左右摄像机移动 */void moveCamera(float speed); /* 前后移动摄像机 */ void setLook(); /* 放置摄像机 */void checkForMovement(); /*检查时候移动*/void CheckedgeCollision(Vector3f oldPos,Vector3f oldView); /*碰撞检测*/首先需要调用setCamera(),初始化相机开始的位置,在本程序中,相机的初始位置设定在场景的中心,方便后边的碰撞检测。然后通过键盘或则鼠标的相应事件,调用相应的函数,判断是要向哪个方向一定。程序中设定“W、S、A、D、Shift”以及键盘上的方向键为相机移动和加速的响应键,当方向键被按下时,调用yawCamera() 函数和moveCamera()函数,获取移动的方向,保存相应的值。同时移动鼠标,调用setViewByMouse()函数,通过计算鼠标移动的角度,获取Camera要旋转的视角。最后调用checkForMovement()函数,检查键盘和鼠标是否移动,如果移动,把上述获取的值赋予Camera,移动相机,实现漫游的效果。对于场景内部的物体,需要做碰撞检测来达到真实性,所以本程序采用了包围盒子的方法,在被检测物体一定小的范围内,设置检测区域,当相机移动到检测区域的边界时,在checkForMovement()函数中调用CheckedgeCollision()函数,做出判断,看是否碰撞到检测边界,如果是,则停止移动,防止穿过被检测物。3.2 地形和天空的绘制实现了全局Camera后,接下来就要绘制基本的框架:地形和天空。对于地形,本程序分为两部分:一部分是高低不平的环绕山,另一部分是平地,用于建造房子等场景。对于天空的绘制,采用了天空盒子的思想,即绘制一个长方体,把所有的场景包含进来。本程序中,设计了一个SkyBox类,用于绘制地形和天空,具体的机构如下:class SkyBoxpublic: SkyBox(); SkyBox(); void CreateSkyBox(); /天空包围盒 void DrawGround(); /绘制地面并纹理贴图void Init(); /初始化地形 Vector3f m_TerrainCoordm_TerrainSize*m_TerrainSize; /网格坐标数据void InitTerrainData(float height); /初始化地形数据 void DrawGrid(int minrow,int maxrow,int mincol,int maxcol);private:GLuint m_Skybox6; GLuint m_Groundtexture2; AUX_RGBImageRec *m_TerrainImage; Texture m_Texture;对于地形的划分,程序采用了46*46个小网格的方法来绘制,存储在m_TerrainCoord 数据中, 对于地形的高度部分,由于高度不统一,所以程序通过调用auxDIBImageLoad()函数,读取一张位图的RGB数据信息,来随机的分配高度,并通过InitTerrainData(float height)函数,初始化纹理的信息。当所有的数据都初始以后,调用DrawGround()函数,绘制地形。对于天空的绘制,首先设置天空盒子的长、宽、高以及绘制原点的坐标,然后调用CreateSkyBox()函数进行绘制。其中,为了实现每个面的链接出没有缝隙,在CreateSkyBox()函数中通过glTexParameteri()函数设置纹理的参数信息,这样就能够实现无缝的链接。3.3场景的绘制地形和天空的基本框架绘制完成以后,就是场景内部物体的绘制。在本程序中,场景比较简单,只绘制了房子和环绕山。其中环绕山在绘制地形的时候已经实现,所以只需要实现房子场景。对于房子的绘制,程序分为四部分:四个墙面、两个斜的屋顶、两个上部的三角墙面和门,通过House类,实现基本的绘制。基本的结构如下:class Housepublic: House();House();void Init();void DrawHouse(); /绘制房子void DrawSurface(); /绘制墙面void DrawDoor(); /绘制门void DrawRoof(); /绘制斜屋顶void DrawRoofOb(); /绘制直屋顶bool open ;private:Texture m_Texture;GLuint m_WallTexture4;房子的绘制比较简单,主要绘制一些基本的线元和小方格,然后绑定纹理的信息。首先是调用Init()函数,初始化房子的纹理信息,然后调用各个绘制函数,实现房子的绘制。3.4纹理和字体类的设计 程序中对于纹理和显示字体的部分,也分别设计了Texture类和Font类,来实现对纹理和字体的调用。具体的结构如下:纹理类:class Texturepublic: bool LoadTexture(char *filename, GLuint &texture); /生成一个纹理,并用texture邦定 bool LoadAlphaTexture(char *filename,char *alphafilename, GLuint &texture,unsigned char compare);void Readstr(FILE *f,char *string); /读取文件中的数据字体类:class Fontpublic: Font(); Font(); bool InitFont(); void PrintText(char *string, float x, float y); protected: HFONT m_hFont;纹理图片的加载,主要通过LoadTexture()函数来读取需要加载的BMP图片,然后通过创建AUX_RGBImageRec 对象来存取读取的位图信息,通过glGenTextures()函数进行产生纹理对象的数量,并glBindTexture()函数和glTexImage2D()函数进行绑定和设置一些参数,实现Texture类的功能。字体类的实现,主要通过创建字体函数,设置在DC中的数据信息和位图数据信息,最终实现屏幕上的打印。具体可以参见代码部分。4 总结 本程序主要是实现简单的三维场景的绘制和漫游,通过把每一个部分进行分类设计,各个类之间相互调用,是程序运行起来效率更高,同时可读性也提高了。全局Camera的控制,能够很好的实现场景全方位的漫游。但场景部分简单,功能不是太多,下一步有点进行添加和改进。 最后自己尝试了通过3Dmax 建模软件导入一个树的模型,但碰撞检测和纹理部分没有处理,只是了解一下导入的过程,为以后做准备。5 程序使用方法介绍 程序可以在全屏模式和窗口模式下面运行,当启动程序后,可以通过“W/A/S/D”和键盘的方向键来控制前后左右移动。Shift键进行加速运动,Tab键用于切换显示模式。移动鼠标来控制视角。当走到门前的时候,可以通过Space空格键来打开门(注意要离门足够近,否则认为距离太远打开),当离开房子的时候,站在门口再次按Space键可以关闭。屏幕运行的界面也有字体的提示。

    注意事项

    本文(基于opengl的三维场景漫游实现(共10页).doc)为本站会员(飞****2)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开