opengl 光源es 如何设置散射光源的方向?

基于Android系统3D引擎的设计与实现-共享资料网
基于Android系统3D引擎的设计与实现
分类号――UDC――密级武多萎理歹大浮学题目位论‘文基王△旦垡[Qi鱼系统墨Q呈l墼的设让皇实现and Implementation of英文Design 题目.尘曼三旦曼ngi壁曼曼垦墨曼亟Qn△盟亟殴i亟墨Y墨!曼也.研究生姓名魏文耀.指导教师姓名―立_赵一职称.―舅址学位―j匠L430070申请学位级别 论文提交日期 学位授予单位工堂亟士 2Q三2生墨且 武这理王太堂学科专业名称 论文答辩日期 学位授予日期 评阅人通信皇信息系统 至Q至2笙墨且答辩委员会主席.趔鱼型亟隧监2012年5月 独创性声明本人声明,所呈交的论文是本人在导师指导下进行的研究工作及 取得的研究成果。尽我所知,除了文中特别加以标注和致谢的地方外, 论文中不包含其他人已经发表或撰写过的研究成果,也不包含为获得 武汉理工大学或其它教育机构的学位或证书而使用过的材料。与我一 同工作的同志对本研究所做的任何贡献均已在论文中作了明确的说 明并表示了谢意。签名:鲡丝喳日期:丝噬血型兰塑I学位论文使用授权书本人完全了解武汉理工大学有关保留、使用学位论文的规定,即: 学校有权保留并向国家有关部门或机构送交论文的复印件和电子版, 允许论文被查阅和借阅。本人授权武汉理工大学可以将本学位论文的 全部内容编入有关数据库进行检索,可以采用影印、缩印或其他复制 手段保存或汇编本学位论文。同时授权经武汉理工大学认可的国家有 关机构或论文数据库使用或收录本学位论文,并向社会公众提供信息 服务。 (保密的论文在解密后应遵守此规定)研究生(签名):姚导师(签名): 武汉理工大学硕士学位论文摘要随着人们生活水平的提高与科学技术的高速发展,在嵌入式设备上开发3D 应用程序将会成为亮点,把3D技术应用到Android产品中,会极大的提高产品 的竞争力。而3D图形开发的过程中所涉及的知识相当广泛,加大了快速开发产 品的难度。基于此问题,本文研究3D引擎技术对常用组件进行封装,以降低产 品开发难度,提高开发速度。首先,本文分析和总结了国内外在Android系统上的3D引擎开发、应用现 状,研究表明目前国内在Android系统的3D引擎的研究处于起步阶段,为此本 文研究基于Android系统3D引擎能够缩小与国外的差距。 然后,主要分析了基于Android系统3D引擎关键技术。先从总体上分析了 在Android系统上3D引擎的框架结构,以及3D引擎各个部分的功能:而后,研究了向量、矩阵、四元数等三维图形学相关的数学知识;接着,分析了3D图 形库OpenGL ES固定渲染管线:最后,详细分析了光照技术、纹理映射和混合 等3D技术。在此基础上,设计实现基于Android系统3D引擎。主要设计实现了:接口模块、数学库、天空盒、公告板、粒子系统、文字显示系统。文中对比了几种 常见的天空模拟方法,综合效率和渲染效果,选取天空盒作为最终的实现。公 告板技术是一个简单实用的组件,用来模拟森林、火苗、立柱。然后从简化物 理模型和对死亡粒子的处理方式等方法上对粒子系统的算法进行了优化,并设 计实现了基于粒子系统的雪景。最后结合了FreeType和OpenGL的优势,实现 了一个文字显示系统,能够实时生成文字对应图片,无需事先完成,节省了内 存空间,由于使用的是TrueType字体,放大也不会产生模糊锯齿等现象。最后,在PC机上搭建Android系统仿真平台,测试了各个模块的功能。实验结果表明,天空盒能较为逼真的模型天空;粒子雪景、雨景也较为逼真的模 拟,文中对比了粒子系统算法改进前后,帧率有明显提升;文字显示系统能够 清晰、无锯齿的在三维空间中显示多种中文字体。本文中采用C/C++作为编程语言,执行效率高于Java语言,适合于在嵌入式Android设备上开发3D应用程序。 因此本文研究基于Android系统的3D引擎技术,能够使开发更加便捷、高效。关键词lAndroid3D引擎OpenGL ES粒子系统FreeType 武汉理工大学硕士学位论文AbstractWiththe improvement of people’S living standard and the rapid development ofonscience and technology,the development of 3D applications will be the highlightembedded devices.The products used 3D technology,will greatly improve the competitiveness of their products.But,3D graphics development involvesrange of knowledge,SO development of 3Dawideonapplications isverydifficult.Basedthis problem,this paper,research the 3D engine componentstotechnology,package commonlyusedreduce development effort and to increase development speed.First,thispaperanalyzes and summarizes the 3D engine developmentontheAndroid system at homeandabroad,and pointed out that domestic research in theAndroid system,theon3D engine in itsinfancy,this paper studiesthe 3D engine basedthe Android system to narrow the gap、析tll foreign countries.Secondly,analyzes analysisof framethe keytechnologyof the 3D engine.From the overallonstructureandvarious parts about 3D enginethe Android system; analysised;Follow,3D mathematical Then weknowledge,vector,matrix and quaternion,Wasanalyzedthefixedrendering of 3D graphics library OpenOL ES pipeline;Finally,a detailedanalysisoflighting technology,texturemappingandblending 3Dtechnology.The mainobjectiveonof this article focusesonthedesign andimplementation of a3D engine based the maththeAndroidsystem.The main modules ale:Interface Module, systems,text display system.library,skybox,billboarding,particleComparison of several common sky simulation method,the overall efficiency rendering,select the skyand andboxtoas arealization.Billboarding technologyisasimplepractical component,usedsimulate theforest,fire,columns.Theandparticle systemalgorithm Was optimized by the simplified physical modelthe approach of deathparticle,designed andtheimplemented snow scence basedonthe particle system.Finally,advantagestextof FreeTypeandOpenGL,thetextdisplay systemCangeneratereal-timepictures,withoutnotprior completed,saving memoryasspace.Whenmagnified,itwouldproduce phenomena suchfuzzy and zigzag,due to the use 一一of TrueType fonts.space display.In武汉理工大学硕士学位论文一―――――-―●----_--_―-_―●_―__―_--―――――-―-_-―--―-____―__―_-_●_____●_―●―――_――一Finally,the simulation platform of the Android system was build,whichto testcanthe function of each module.The experimental results show that the sky box more realistic;particle snow and particle rainarebealso more realistic。in contrast to theframe rate has improved significantly before and after the improvement of the particlesystem algorithm;text display systemtobeabletoclear the jagged three.dimensional Was used,SO thethis paper,C/C++programming languageimplementation has high efficiency,which suitable for the development of 3D applicationsonembedded devices.In thispaper,basedontheAndroidsystem's 3Dengine technology,will enable the development more convenient and efficient.Keywords:Android,3D engine,OpenGL ES,Particlesystem,FreeType 武汉理工大学硕士学位论文目录第1章绪论……………………………………………………………………………l 1.1课题研究背景及意义………………………………………………………….1 1.2国内外研究现状…………………………………………………………………2 1.3论文的工作及章节安排……………………………………………………….3 第2章3D引擎关键技术分析………………………………………………………52.13D引擎…………………………………………………………………………..5 3D引擎结构………………………………………………………………一52.1.12.1.2基于Android系统3D引擎结构…………………………………………62.1.32.2Android系统中的JNI技术………………………………………………。73D数学模型……………………………………………………………………82.2.1向量………………………………………………………………………………………………..82.2.2矩阵………………………………………………………………………………………………。92.2.3四元数…………………………………………………………………………………………….92.3 OpenGL ES…………………………………………………………………………………………..1 12.4 OpenGLES渲染管线……………………………………………………………ll2.4.1固定管线渲染流程………………………………………………………ll 2.4.2光照技术…………………………………………………………………1 3 2.4.3纹理映射…………………………………………………………………….1 5 2.4.4混合………………………………………………………………………………………………l 6 2.5本章小结……………………………………………………………………….17 第3章3D引擎设计与实现………………………………………………………….1 83.13D引擎需求分析…………………………………………………………………183.2接口模块设计与实现……………………………...……………………………1 8 3.3基本数学库实现……………………………………………………………….19 3.4渲染系统………………………………………………………………………..22 3.4.1视窗模型………………………………………………………………………223.4.2天!空………………………………………………………………………………………………2:I3.4.3公告板………………………………………………………………………26 武汉理工大学硕士学位论文3.5粒子系统………………………………………………………………………28 3.5.1粒子系统原理……………………………………………………………一29 3.5.2基于粒子系统的雪景设计………………………………………………30 3.5.3基于粒子系统的雪景实现……………………………………………….31 3.5.4粒子系统改进算法……………………………………………………….34 3.6文字显示系统…………………………………………………………………353.6.1 FrecType…………………………………………………………………………………………35 3.6.2FreeType主要接口介绍………………………………………………….363.6.3基于FreeType文字生成…………………………………………………37 3.6.4滚动文字实现……………………………………………………………。39 3.7本章小结………………………………………………………………………40 第4章仿真及结果分析…………………………………………………………….41 4.1仿真平台搭建…………………………………………………………………4l 4.2实验效果及结果分析………………………………………………………….42 4.2.1天空盒……………………………………………………………………42 4.2.2粒子场景………………………………………………………………….43 4.2.3文字显示………………………………………………………………….48 4.3本章小结……………………………………………………………………….50 第5章总结与展望………………………………………………………………….5 l 5.1全文工作总结…………………………………………………………………5 l 5.2下一步工作展望………………………………………………………………52 致谢………………………………………………………………………………………………………….53 参考文献…………………………………………………………………………….54 武汉理工大学硕士学位论文第1章绪论1.1课题研究背景及意义本课题“基于Android系统3D引擎的设计与实现”是在某公司3D UI开发 项目中提出来的。 随着计算机技术的发展,硬件性能可谓是突飞猛进,软件日新月异、丰富 多彩。计算机的发展同时促使了图形学飞速发展,现在各行业中的都有广泛的 应用,而且三维计算机图形学的时代已经到来,三维图形已经深入到我们生活 工作的方方面面IlJ。随着社会的进步,用户对游戏、用户界面等的视觉效果要求 越来越高,如今三维游戏、三维用户界面已经是一个不可逆转的趋势。 三维图形开发过程中经常要涉及大量的算法、计算机图形学和图形库(API) 的知识【2】【3】,因此要快速开发三维应用程序是有相当的困难的,就需要一个封装 了硬件操作和图形库的开发环境,这个环境对于应用开发人员来说,简单易用、 功能丰富,不需要知晓计算机图形学的实现细节。这样的一个开发环境可以被 称作为三维引擎(即3D引擎)。 3D引擎是软件工程中的软件复用思想在3D场景开发中的表现形式之一。 它把最常用、核心的功能进行了有效的封装,形成通用的框架模块。这样,场 景开发人员就可以不必去关心场景的底层实现细节,而直接调用3D引擎提供的 现成功能,在短时间内高质量地开发出新场景新游戏【41151。总的来说引擎应当具 有以下几个特点: (1)驱动性:在功能上支持某方面应用,但是实现细节却是依赖于应用。 (2)完整性:完整的实现某个功能。 (3)独立性:不依赖于某一个具体的应用程序。【6胴 3D引擎技术不仅在游戏领域有了广泛深入的发展,而且在虚拟现实、建筑 虚拟、城市规划、房地产开发、教育等各方面都有广泛的实际应用。IS】 随着嵌入式设备的性能提高和3D图形技术在嵌入式领域的应用,在嵌入式 设备上开发3D场景和3D游戏将会成为一个新的亮点。经过多年的发展,无论 从技术上还是市场消费趋势,智能手机已经成为手机发展的主要潮流。而当下 的手机系统中,Android无疑是最流行,也是最受大家欢迎的一款手机操作系统。 武汉理工大学硕士学位论文由于Android系统底层是基于Linux内核的,而且是开源、免费向广大用户开放,因此它很快得到了广大开发者和众多手机厂商的支持f9】。因此对基于Android系统的3D引擎的研究势在必行,能够使开发更加便捷、高效。1.2国内外研究现状目前,国外研究嵌入式3D游戏引擎的热情是非常活跃的。国外研究三维游 戏引擎的公司主要有,3DRealms,IdSoftware,Valve等等【l们,这些公司研发了一批非常优秀的三维引擎,大家熟知的有Quake,Quake II,QuakeIII,Half-Life 等等。自2000年后,随着游戏产业的发展,相继出现了很多开源的游戏引擎开 发组织,也研发出了一些非常优秀的开源游戏引擎,如ORGE、Irrlicht等等。【ll】 虽然开源引擎在品质上无法与商业引擎相比,但其免费性和开源性的优势,受 到大批人士的热捧。商业引擎和开源引擎共同推动了三维游戏引擎的发展和壮 大。 麻省理工学院(MIT)是一个一直走在最新技术前沿的科学研究机构。MIT 原先就是研究人工智能、机器人和计算机图形学以及动画的先锋。这些技术都 是虚拟技术(VR)的基础。1985年成立了媒体实验室,进行虚拟环境的正规研 究。媒体实验室建立了一个名叫BOLIO的测试环境,用于进行不同图形仿真技 术的实验。利用这一环境,MIT建立了一个虚拟环境下的对象运动跟踪动态系 统。【12】 SRI研究中心建立了“视觉感知计划",研究现有VR技术的进一步发展。 1991年后,SRI进行了利用VR技术对军用飞机或车辆驾驶的训练研究。另外, SRI还利用遥控技术进行外科手术仿真的研究。【12】 著名的Fathammer公司开发的X.Forge引擎拥有一套全面的开发技术和工具 集,使它能够在多种现有的嵌入式平台上开发出高品质的3D游戏。X.Forge采 用了两层构架,底层提供硬件抽象和对操作系统的支持,上层提供与平台无关 的3D图形场景管理和游戏世界管理模式。X.Forge 2引擎对开发者来说更加易 于使用,更加注重于美术工具,实现更逼真的3D效果。X.Forge 2引擎仍然保 留了上一版的模块可裁剪性,因此引擎有很大的灵活性。【131随着Android系统的发展,在Android系统上也已经涌现出一批非常小巧实用的图形引擎,如ES3D、Catcake、Rokon、Libgdx等。实质上ES3D都不能算 是一个引擎只是对OpenGL EStl4】【15l【161做了一个简单的封装;Catcake是一款跨平2 武汉理工大学硕士学位论文台的Java 3D图形引擎;Rokon和Libgdx是Android 2D游戏引擎;从实现上来 看这些游戏引擎都较为简单,长远看很难满足后续的发展。 随着游戏产业的迅猛发展,国内开发拥有自主知识产权的3D游戏引擎,特 别是3D图形引擎的呼声越来越高,因为3D图形引擎是整个3D游戏产业的核 心技术【l‘71,它的发展总是伴随着计算机软硬件领域的最新研究成果,其品质的 高低直接决定着游戏质量和价值。 就国内情况而言,2000年后,出现了一些独立自主研发游戏引擎的企业, 但是都是投入不大,很难与国外相比,如金山、巨人网络和网易等互联网公司118】。 国内研发的手机3D游戏引擎的有:龙骨(Dragon Bone)是北京数位红软件应 用技术有限公司;X.Factory是天津市天大北洋软件开发有限公司开发的基于 Symbian平台的高性能手机游戏开发引擎。【I9】但是国内大部分的游戏开发公司都 采用国外的游戏引擎,或者是在开源引擎的基础上进行开发,对3D游戏图形引 擎的研究还是停留在初级阶段,大多仅限于使用现成的3D引擎,来开发3D应 用程序、游戏等等,目前无法与国外的3D引擎相抗衡,使得开发成本大幅度增 加,阻碍了在国际市场上与国外的竞争。 当下,嵌入式设备的软硬件性能越来越高,3D图形技术应用越来越广泛,以及Android系统的迅速发展,在Android上开发3D场景和3D游戏的需求将 会越来越大【2们,因此对于Android系统上的3D引擎的研究将是研究的热点,而且具有明显的现实意义。1.3论文的工作及章节安排 本文在Android系统的基础上较为全面的介绍了3D图形引擎的结构、功能以及相关的3D关键技术,并且给出了关键技术的实现方法。本文是在充分研究了OpenOL ES 3D图形库的基础上,理论结合实践,对关键部分大场景渲染进行了详细的论述。还介绍了在Android系统上C/C++3D引擎的架构等。本文的创新点是在Android嵌入式系统上实现了一个大场景绘制的图形引 擎。在本文中没有采用Android系统的J2ME的原因是,Java程序执行效率低下,C/C++更适合于在嵌入式设备上开发3D应用程序,底层采用的是OpenGL ES标 准,这样能够实现高效性和与具体的硬件设备无关,方便于更新升级。 本文中的具体章节安排如下: 第一章主要介绍了3D引擎的基本概念,3D引擎国内外研究发展现状,后3 武汉理工大学硕士学位论文面介绍了论文的主要工作和创新点,给出了论文各章节的安排; 第二章主要详细研究了3D引擎技术。3D引擎的构架以及在Android系统 上3D引擎的构架进行详尽介绍;研究了3D数学相关知识、3D图形API,以及 三维图形库OpenGL渲染技术。 第三章主要是实现3D引擎关键技术。设计实现了3D引擎与Android系统 的接口模块,以及几个重要的组件:数学库、天空盒、公告板、粒子系统、文 字显示系统。 第四章主要是搭建Android系统仿真平台以及对实验结果进行分析。 第五章主要是对全文的总结和未来工作的展望。对全文进行总结,之后指 出文中需要进一步完善的地方,最后展望后续研究工作。4 武汉理工大学硕士学位论文第2章3D引擎关键技术分析3D引擎是3D游戏或者3D应用程序中最关键的一个部分,有超过50%的CPU时间是花费在图形渲染上面的【211。若是没有3D引擎我们将什么都看不到,3D引擎让整个场景可以看得见摸得着,用户可以通过显示的状态进行选择,完 成想要的操作。2.13D引擎3D引擎是3D应用程序的核心代码,能够控制整个程序的执行流程。对三维图形库进行了有效的封装,因此开发人员不需要花太多的时间和精力去关注 系统构架、资源加载、内存使用、以及如何调用三维图形API(应用程序接口) 进行图形绘制,从而可以节省大量的时间缩短3D应用程序的开发时间。2.1.13D引擎结构3D引擎主要功能模块基本上包括:场景管理,GUI系统,交互系统,内存 管理系统,资源管理系统,数学库,调试系统,3D图形库等八部分。如图2.1 所示:核心模GuI系统I场景管理(SceneNemager)I交互系统l粒子系统l|文字显示系统I l模型管理r。 。 。’_?_ I。_-o一●1_ _-_。 。‘。 。一●o-_ ‘。 。 。 。‘ ‘一兰竺!!竺兰 ][I内存管理l l资源管理||数学库||调试系统II图形库l L――――――――――――J!!――――――――.JL――――――――――J L....――――――_J网网回网L........――-J图2一l 3D引擎结构框图(1)场景管理(Scene Manager):一个场景代表在虚拟世界中显示的物品。 在整个3D世界中,场景与场景之间相关、从属、影响与被影响的关系是通过场 景管理组织起来。5 武汉理工大学硕士学位论文(2)交互系统:交互系统就是实现3D引擎与用户(即使用者)的通畅通 信。处理用户的输入并且将处理的最终结果反馈给用户。一般包括鼠标、键盘、 触摸屏等等。 (3)GUI系统:GUI就是图形用户界面(GraphicalUser Interface)。GUI系统中的图形界面的任务就是将数据解释成用户能理解的信息。它能够获取终 端用户和系统的交互事件,处理并改变当前的数据,最后通过图形界面将数据 的变化反馈给终端用户。 (4)内存管理系统:内存在计算机中是非常稀缺的资源,尤其是在嵌入式 设备当中表现尤为稀缺。当今对3D场景的要求逼真程度越来越高,内存的使用 量也越来越大,所以需要内存管理系统合理配置资源。 (5)资源管理系统:3D引擎在实际使用中需要加载各种文件,例如各种格 式的图片、3D模型。支持文件格式的多少直接影响到后期的开发,越多越能灵 活的开发应用程序。对使用的资源实现统一管理,能够保证所使用的资源调度 准确和高效。 (6)数学库g数学库在实际使用中主要提供向量、矩阵、四元数等计算机 图形学方面的数据结构和算法。 (7)调试系统:调试系统是将系统的状态通过屏显或者LOG方式,实时 显示整个系统的状态,既能方便编写应用程序,同时又可以方便出错时候查找 定位错误,从而加快整个3D应用程序的开发进程。 (8)3D图形库:3D图形库这里主要是指3D图形应用程序接口(3D图形 API),在PC机上一般有两种OpenGL和DircetX。在嵌入式设备是OpenGLES。2.1.2基于Android系统3D引擎结构Android是Google历经数年和投资数亿开发出来的智能手机操作系统,它 是一个开放的系统,任何公司个人都可以参与其中,随着各大移动终端生产商大力开发和生产基于Android的移动智能设备,Android迅速得到了业界和社会的认可,并成为整个产业的热点I列。在Android系统中,系统的特性要求最上层的应用必须是Java编写,整个应用的框架是Java,这样能够很好的实现应用程序的移植∞l。众所周知Java是一种解释性编程语言,需要Java虚拟机(ⅣM)来解释执行,执行效率很低。而3D图形应用程序执行的过程中一大半的执行时间都是在绘制图形,Java的效6 武汉理工大学硕士学位论文率显然是不能胜任的,因此在本文中选用的一个策略是将3D引擎的主体代码使 用执行效率更高的C/C++语言来编写。基本框架如图2.2所示:lI J-v。枉繁+JSI接n ‘车地程序)●3吲?每矗●Android幕缱平台图2-2 Android系统3D引擎框架图在Android系统中,一个应用程序的起始点必须是从Java层开始,因此在Java层完成应用程序的初始化,以及时间事件和消息处理等等,将引擎的主体 代码放在C/C++用来提高执行效率。上层使用Java,而我们的3D引擎是用C/C++ 来开发,因此需要一个桥梁连接C和Java,而JNIt24】(Java Native Interface)能 够很好的实现这一功能。JNI是本地编程接口允许Java代码与其它语言写的代码 进行交互。在Java中初始化进程之后,就可以转而通过JNI对3D引擎进行初始 化,最后完成场景的绘制。 3D引擎的底层是封装OpenGL ES,将引擎的功能封装成类以供调用,事件 响应(如键盘、鼠标、触屏事件)这一部分,无法在C/C++层得到,因此在实现 过程中是在Java层去获取事件响应,然后通过声明的native函数,传递给JNI, 最后再由相关本地程序去实际响应这些事件处理。2.1.3Android系统中的JNI技术JNI是Java Native Interface的缩写,中文为“Java本地接口"。从Javal.1开始,JNI标准成为Java平台的一部分,它允许Java代码与其它语言写的代码进行交互。在Java虚拟机(VM)内部,能够完成Java代码与C/CH代码进行函数相互调用,相互访问存储单元【241。 Android系统中JNI,目的也是让Java程序和C/C++程序交互。系统中有大 量的接口是通过在Java中声明native函数,在本地实现了这些接口的功能,并 将其注册进系统,这样可以提高系统运行的速度。Android系统中JNI框架如图2.3所示。 武汉理工大学硕士学位论文图2-3 YNI在Android系统层次中的作用在应用程序中,通过“System.10adLibrary0’’函数加载指定的库。当虚拟机 执行“System.10adLibrary0"函数时,首先执行本地库中的“JNI OnLoaa()"函 数,释放该本地库的时候调用本地库中的“YNI UnOnLoadO"来实现清理工作【251。 在应用层中执行本地函数时候,需要虚拟机在本地库中查找相应的本地函 数,如果这个函数频繁呼叫,势必影响整个程序的执行效率,在Android系统中 是通过“registeNativeMethods0"函数把本地函数注册到虚拟机里。这样就不必 进行查找,加快执行效率。 2.23D数学模型在3D引擎中,模型动画、场景渲染、描述对象物体之间的关系等等都会使用到大量的3D数学知识。本节对这些基本数学知识进行详细分析。2.2.1向量在三维空间中,向量指的是空间向量。在空间,我们把具有大小和方向的 量叫做向量。 向量可以表示为两点间的差值。 向量矿=(rx,匕,K)=丑昱=(屯一却儿一M,z2一z。),其中,%,巧,圪是向量V在 而弘z轴上的投影,即而弘z分量。向量的大小为:IVl_√■2+02+屹2,其运算法则如下:向量的加法:K+圪=(K,+K,,K,+匕,,K:+圪:) 向量的标量乘法:Ay=(九圪,A屹,A圪) 向量的数量积:K?吒=K,%,+Ky%y+巧:K。 向量的叉积:K×匕=(Ky吒:-g,:Ky,巧:%,-g,,圪:,K,%y-g,y圪:)8 武汉理工大学硕士学位论文2.2.2矩阵在数学上,矩阵是指纵横排列的二维数据表格,这些数值一般都为实数, 即矩阵元素。矩阵最早来自于方程组的系数及常数所构成的方阵。这一概念由 19世纪英国数学家凯利首先提出。在3D引擎中一般使用的是方阵,即矩阵的行 数和列数是相同的。 矩阵在三维空间中可以用来描述物体的几何变换,常用的有平移、旋转、 缩放等等。在三维坐标系中,任一点P(x,弘z)变换后的点为尸,(r,y?,z?)。x0 0 1t。 ty t: 1(a)平移变换矩阵表示:.●zy0rsl0sy0 0s:(b)缩放变换矩阵表示:y∥●0 0 O0 00(c)旋转变换矩阵表示:r l0 cose sin0 00 -sin9 COSp O绕X轴旋转:0 0 O.rcosO 0 ..sin0 0sin0 0 COS0 0X绕Y轴旋转:y.,Z 0 0 0 O 1 Z●yrcosO-sin0 sin0 0绕Z轴旋转:少∥●cos#0 0 0 l 00其中参数p表示按坐标轴旋转的角度,如果用却代替旋转角日可得到逆旋转矩阵。旋转角取正将按逆时针方向旋转; 取负值将按照顺时针方向旋转。2.2.3四元数9 武汉理工大学硕士学位论文四元数(Quatemions)是由威廉?卢云?哈密顿(William 1805.1865)在1843年爱尔兰发现的数学概念。【26】RowanHamilton,四元数是最简单的超复数。Hamilton将实数加上三个元素凡,、k组成四元 数,即四元数一般可表示为:q=w+xi+yY+zk,其中愀矗弘z都是实数;参 f、j『、k服从以下关系:f2=J2=k2=-1,iy=一∥=k,jk=一移=厶ki=一ik=J。 使用四元数来表示旋转通常是一个很好的方法。在多数情况下用四元数替换旋 转矩阵有很多好处,四元数占用的存储空间很少,所需算术运算符更少,并且 更容易编辑和修改。四元数q=w+耐+Jc|『+妇的模的定义式为:Iql=w2+f2+_,2+七2。所有满足Iql=l的四元数,被称为单位四元数(unit quatemion)。四元数运算法则:假设有ql=M+xli+ylj+Zlk,q2=w2+而f+儿歹+z2k则 (a)四元数的加法:ql?q2=(wlw2一而岛一M奶一zlz2)+(M恐+五w2+ylz2一毛奶y +(wl儿一xlz2+y,w2+乙屯)_,+(w,z2+而儿一咒而+z,w2)(b)四元数的乘法:ql?q2=(Ⅵw2一而屯一乃奶一毛乞)+(嵋而+而w2+ylz2一zl奶y +(wl儿一而乃+Mw2+ztx2)j+(wlz2+而奶一M屯+毛w2)(c)四元数的点乘:ql?92=(Ⅵw2+而屯+M奶+zl乞)四元数旋转特性:假设有任意旋转轴的向量为y(毛,咒,乙),其旋转角度是 9,如图2.4所示:V图2.4绕向量V旋转口角度 那么可以使用四元数q表示该旋转,其中:w=cos(O/2),x=‘?sin(O/2) Y=儿?sin(O/2),z=z,?sin(O/2)即可以得至U q=cos(O/2)+Vsin(O/2)。10 武汉理工大学硕士学位论文2.3 OpenGL ESOpenGL(Open GraphicsLibrary),它是独立于硬件的底层图形库软件接口,具有很好的移植性和较高的渲染效率。它是开放的3D图形库,独立于窗口系统 和操作系统。12 7】自1992年7月,SGI公司发布了OpenGL的1.O版本以来,OpenGL 发展迅速,在2011年8月Khronos发布了新的OpenGL 4.2标准。OpenGL能够 实现对二维和三维图形渲染,从而绘制出形态逼真的三维场景。OpenGL ES(OpenGL for EmbeddedSystems)是专门为嵌入式系统而订制的3D图形API。12810penGL ES是OpenGL的子集,是从OpenGL裁剪定制来的,裁剪了glBegin/glEnd,四边形(GL.-QUADS)、多边形(GL--POLYGONS)等复 杂图元等许多非绝对必要的特性。OpenGL ES本身是底层基础库,不提供实体 的几何图元,只提供点、直线和多边形等三种简单图元来构建场景模型。但在 实际中,我们可以通过一些转换就可以讲3D MAX、3DS等建模软件制作的模 型转换成OpenGL ES顶点数据。 2.4 OpenGLES渲染管线渲染是指计算机根据模型创建图像的过程【29】。在OpenGL中,渲染过程总 是按照一定的操作顺序对数据进行操作,我们将这个操作处理过程叫做OpenGL 渲染管线。2.4.1固定管线渲染流程模型(或物体)是由几何图元(在OpenGL中指点、直线、多边形、图形 和位图等)构成的,而几何图元是通过顶点来指定的。最终渲染的图像由屏幕 像素组成。像素(pixel)是显示硬件能够放置到屏幕上的最小的可视元素,像 素信息在系统中组织成位面(bitplane),位面构成了帧缓存。【30】 图形渲染步骤:首先采用几何图元建立物体模型;其次是在三维世界中按 需求排列物体位置:然后是计算物体的颜色,颜色是顶点色和光照共同决定; 最后是光栅化,即将物体位置、颜色等信息转化为屏幕能够显示的像素数据。 OpenGL的渲染流水线包含:显示列表、求值程序、顶点操作、图元装配、像素 操作、纹理装配、光栅化、片断操作等。poJ如图2.5所示: 武汉理工大学硕士学位论文图2-5 OpenGL固定管线框图(1)显示列表:将图元、像素数据,函数存储到显示列表中可提高性能。 (2)求值器:我们可以使用求值器的控制点来计算曲面的顶点信息,它能 够生成表面纹理、法线、颜色和空间位置。 (3)基于顶点的操作:对于顶点数据,将顶点变换成图元的操作过程。 (4)图元装配:主要内容就是裁剪,这个阶段的结果就是完整的几何图元, 也就是根据相关的颜色、深度进行了变换和裁剪的顶点。 (5)像素操作:把内存或者帧缓冲区中像素数据读取出来,对它们进行像 素转换操作(缩放、偏移、映射和裁剪),然后经过一道像素转换,最后写入到 纹理内存或者帧缓冲区中。 (6)纹理装配:在物体上使用纹理图像,使物体更为逼真丰富。 (7)光栅化:即将物体位置、颜色等信息转化为屏幕能够显示的像素数据。 (8)片断操作:在数据被真实存放到帧缓冲区之前,会执行纹理处理、组 合主颜色和辅助颜色、雾计算等其中的某些操作,而这些操作或许会篡改或丢 掉这些片段。前面的这些操作生成了最终的颜色和深度之后,执行可用的裁剪 测试、alpha测试、模板测试和深度缓冲区测试。最后经过完整处理的片断就被 绘制到适当的缓冲区中,最终到达屏幕进行显示。【3l】 OpenGL固定图形渲染管线可以粗略地认为由下面的阶段衔接而成,如图 2.6所示:12 武汉理工大学硕士学位论文图2-6 OpenGL固定管线渲染流程图顶点颜色,光照,材质三个输入在光栅化前控制绘制管线的操作。光照和 材质不能单独使用。顶点颜色,光源颜色,材质颜色都有Alpha值,它们的Alpha 经过运算最后会保存在光栅化后的图元中,也就是说它们的影响也就在上图中 虚线上方。【32】输入是顶点(几何坐标、顶点颜色),矩阵,光照(光源,参数), 材质,输出是片元。纹理映射的过程的本质是根据纹理信息对片元的再处理, 这个过程可能会改变片元的Alpha值,输入是片元,纹理(纹理坐标、各种参数), 输出还是片元。Alpha值最终通过Alpha混合阶段影响绘制效果,输入是片元, 输出是帧缓存颜色值。2.4.2光照技术当观察一个物体表面时候,眼睛对颜色的感知取决于到达和刺激锥细胞的 光子的能量分布。这些光子可能来自单个光源,也可能来自多个光源。有些光 子被表面吸收了,有些光子则被表面反射。另外,不同表面的属性可能存在这13 武汉理工大学硕士学位论文非常大的区别。有些表面非常光亮,会把光线反射到某个方向。有些表面则把 入射光均匀的发散到所有的方向。绝大多数表面都位于两者之间。 在OpenGL光照模型中,将光可以分成为红、绿、蓝三种独立的颜色成分, 即RGB颜色【33】。所以,光源发射的光的颜色是由其中红、绿和蓝光的数量而定。 同样,向各个方向反射的红、绿、蓝光的数量就组成了其材质属性。 在OpenGL光照模型中将光细分为4中独立的成分:环境光、散射光、镜 面光、发射光【341。各个成分可以独立计算,然后合成为最终最后的效果。 (1)环境光(ambient light):经过了非常充分的散射,已经没有办法分出 它来自于那个方向的光。特点是无方向性,不衰减。把环境光亮度记为L,物体的表面的环境光反射系数(ambientreflectioncoefficien)记为K。,物体表面所呈现的亮度为L。因此我们可以得到环境光的计算方程如(2.1): L=Ko×Io(2-1)(2)散射光(diffuse light):当它撞击表面时它会均匀地向所有的方向发散。 特点是均匀发散,有衰减。^光■'《Z式.图2.7漫反射光强度与入射角的关系 如图2.7所示,设光源亮度为,。,P点的法向量为N,从点P到点光源之间的向量L,p为N与L的夹角,屹“O,l】,表示漫反射系数。则得出P点的漫反射光亮度厶如(2.2)所示:厶=‘髟coscos0,0∈(o,{)二(2-2)(3)镜面光(specular light):来源于某一个方向的光,经过表面所有光线 反射方向相同。镜面光一般可以表现具有光泽度的物体,如金属、塑料等,而 像毛线和棉布这样表面粗糙的物体镜面光成分很少。特点是光泽,有衰减。 (4)发射光(emissive light):顾名思义就是材料表面发出的光。它是物体 自身的状态,不受光源的影响。14 武汉理工大学硕士学位论文当使用OpenGL命令glEnable(GL--LIGHTING)后,OpenGL状态机的绘制模 式转为使用光照模型: (A)绘制场景时,在OpenGL光照模型中,最多支持加入8个光源,光源 的开关相互独立。而且OpenGL假定光源只对吸收或反射光线的表面产生影响。 (B)同时,每个表面都认为由不同属性的材质构成,材质可能将入射光散 射到各个方向,可能将大部分光线反射到特定方向,材质本身也能产生光线。 只要当前的绘制是使用光照模型,那么材质属性就要被计算,材质是 OpenGL状态机中的一组状态,五个参数,如表2-l所示: 表2.1光照模型五参数及其默认值不论其他参数的Alpha值为多少,顶点Alpha值就是材质散射颜色(GLDIFFUSE)的Alpha值。物体的颜色很大程度上受散射光的影响,它取决于入射光的散射分量和入射光相对物体表面法线的角度(角度越小,散射光强 越大),和视点无关。真实世界中的散射光和环境光通常是同样颜色。 (C)OpenGL光照模型将光照(光源和拥有材质属性的物体表面作用后的 视觉效果)分成四个独立的成分:环境光(ambient)、散射光(diffuse)、镜面反 射光(specula)和发射光(emission)。四种成分独立计算然后混合到一起13引。2.4.3纹理映射纹理映射的概念最早是由Catmull在1974年提出来的,纹理映射就是按照 投影函数将纹理图像和几何曲面相对应起来,这一个过程就叫做纹理映射【351。 在实际应用中,纹理可分成一维、二维和三维纹理。最广泛使用的是二维纹理, 它可以很方便的用位图来表示一个纹理。 纹理映射的基本思想就是确定物体空间上的一点与纹理表面上一点(Ⅳ,’,)的 武汉理工大学硕士学位论文对应关系,这种对应关系通常是通过一个投影函数来实现的。纹理映射的整个 过程可以用一个统一的纹理管线来描述。如图2.8所示:茎蒿茬釜H髫髭,蔫H燃H应鬻换H对主荐蓉扩图2-8纹理映射管线当使用OpenGL命令glEnable(GL TEXTURE2D)后,OpenGL状态机控制下 的绘制流程中将会加入纹理映射这一步骤,其操作步骤如下: (A)OpenGL程序中设置纹理映射,通常的步骤是: (1)使用glGenTextures0得到一个纹理序号。 (2)使用glBindTexture0使用纹理属性的默认值来创建一个纹理对象。 (3)使用glTexImage2D0在纹理对象中存储数据。 (B)OpenGL程序中在完成上面的步骤后应该使用glTexParametcr*0设置 纹理映射的几个参数: (1)在纹理贴图映射到片元时,放大和缩小需要指定某种滤波方式。glTcxParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE MAG_FILTER,GL-上INEAR);(2)在处理不在【0.O,1.O】的纹理坐标时,需要指定覆盖重复方式。glTexParameteri(GL--TEXTURE_2D,GL--TEXTURE_WRAP―S,GL_REPEAT); glTexParameteri(GL TEXTUREWRAP T D2_, , GL TEXTUREGL_REPEAT);2.4.4混合混合就是把两种颜色混在一起,来实现半透明效果。混合中把将要绘制的 颜色叫做为“源颜色",原颜色叫做“目标颜色"。在OpenGL中,源颜色、目 标颜色计算是需要乘以一个系数(与源颜色相乘的是“源因子",与目标颜色相 乘的是“目标因子"),然后就能得到所需的颜色。我们使用数学来表示一下混 合的过程,假设源颜色表示为是(如,Gs,Bs,As), (Rd,Gd,Bd,Ad),源因子表示为(St,Sg,鼬,sa), (Dr,Og,Db,Da)。则混合的结果如(2.3)所示: 目标颜色表示为 目标因子表示为(如?跏+Rd*Dr,Gs?Sg+Gd?Dg,Bs?鼬+Bd?Db,As*Sa+Ad?Da)在OpenGL中,启用混合调用glEnable(GL16(2-3);)DNELB.调合混闭关 武汉理工大学硕士学位论文glDisable(GL_BLEND);通过glBlendFuneOi蚕l数设置源因子和目标因子,第一个 参数表示源因子,第二个参数目标因子。这两个参数有多种值,如表2.2所示: 表2.2源混合因子和目标混合因子2.5本章小结本章主要研究了3D引擎相关技术。首先介绍了什么是3D引擎,它都有那 些功能,详细介绍了3D引擎的框架结构,以及在Android系统中3D引擎的结 构。第二个方面是研究了向量、矩阵、四元数等3D数学理论。然后是对三维图 形应用程序接口OpenGL进行详细的研究。最后对光照系统、纹理映射、混合 方面的理论进行了详细的阐述,并且对在OpenGL如何使用进行了简单的介绍。 武汉理工大学硕士学位论文第3章3D引擎设计与实现3 103D引擎需求分析在前文中,经过对3D引擎框架,3D数学知识和OpenGL ES的研究,实现其中主要的模块有:接口模块、数学库、天空盒、公告板、粒子系统、文字显 示系统。引擎应当要能达到以下目标: (1)真实感:逼真的模拟天空、雪景雨景。 (2)天空盒组件,能够将相应的天空纹理连接起来形成室外大环境。 (3)公告板组件,能够随着镜头的旋转始终保持面向镜头。 (4)粒子系统组件,能够真实的模拟雪景雨景,算法改进后能够显著的提 高显示帧率。 (5)文字显示系统能够加载多种字体,在空间中显示文字清晰无锯齿。3.2接口模块设计与实现在Android系统中,有四大组件:活动(Activity)、广播接收器 (BroadcastReceiver)、服务(Service)、内容提供者(Content Provider)[36J。其 中活动是最基本的组件,在应用程序中,一个活动就是一个屏幕显示,即一个 界面。活动将会显示由视图(View)空间组成的用户接口,并且对事件(Event) 做出响应。活动(Activity)是有生命周期的,因此在设计接口的时候要充分考 虑活动(Activity)的生命周期。 由于3D引擎的主体代码是C/C++编写,因此在Java部分必须声明本地函数 (native),然后在通过JNI再执行真正的引擎代码。如下是本地函数声明,其中 nativeOnCreateO、nativeOnPause0、nativeOnResume0、nativeOnDestroy0[]个函 数是为了配合Activity的生命周期的而设计。nativeInitGLO是用来初始化引擎, 初始化3D场景等操作。nativeResize0是用来设置3D程序屏幕大小,设备屏幕 大小一般是通过系统回调函数取得,然后通过本函数对引擎底层进行设置即可。 nativeSendTouchEventO、nativeSendKeyEvent()这两个函数是从系统获取键盘事 件和触屏事件,并将事件代码发送给引擎进行处理,其中将事件代码封装成 武汉理工大学硕士学位论文TouchEvent和KeyEvent这两个类。nativeUpdate0函数是用来绘制当前帧。public class Himalaya{public static native void nativeOnCreateO; public static native void nativeOnPause0; public static native void nativeOnResume0; public static native void nativeOnDestroyO; public static native void nativelnitGL(); public static native void nativeResize(int w,int h); public static native void public static,nativeSendTouchEvent(TouchEvent event);nativevoid nativeSendKeyEvent(KeyEvent event);private static native void nativeUpdate();} 在Android系统中,显示由视图(View)来完成,我们这里的View是用的 GLSurfaceViewta7】,我们要重写这个类,这个类中最重要的一个方法是publicboolean onTouchEvent(final MotionEventevent),当有触屏事件发生时候,系统会调用此方法,将触屏事件类型,位置等信息存储在MotionEvent的对象中,然后 将这个事件通过nativeSendTouchEvent发送给引擎。 使用GLSurfaceView创建3D场景,需要我们重写Renderer(渲染器),它 继承于GLSurfaceView.Renderer我们要实现其种的三个方法:onSurfaceCreated0,onSurfaceChanged0,onDrawFrame0。onSurfaceCreated0是当Surface创建的时候调用,因此可以将引擎初始化代码放在此处,即调用nativelnitGLO。 onSurfaceChangedO是当Surface变化时调用,如渲染屏幕更改大小等,其中可调 用nativeResize0。onDrawFrame0是用来绘制当前帧,即可调用nativeUpdate()。3.3基本数学库实现数学库在实际使用中主要提供向量、矩阵、四元数等计算机图形学方面的 数据结构和算法。向量、矩阵、四元数主要是在3D世界中提供几何变换如平移、 旋转、缩放等等。以及计算点与点关系,点与面关系,面与面关系,线与面之 间关系等等。 在数学中不管是什么类型的数据,所要进行的操作往往是相同的,因此本19 武汉理工大学硕士学位论文文实现中使用了C++中的模板类实现方式,按照不同的数据类型重复定义相同 的实现方式,需要浮点数(float)就实例化float类型的模板即可,需要整数(int) 就实例化int类型的。这样在实际中即简单又增加了程序的可读性。(1)向量(vector3d)向量在使用过程中一般有三维向量和四维向量,最常用的是三维向量,下 面是三维向量(vector3d)的实现,并给出了接口。template<class T> class vector3d{ vector3d<T>operator+(eonst vector3d<T>&other)const; vector3d<T>operator-(const vector3d<T>&other)const;T dotProduct(constvector3d<T>&other)const;//点积vector3d<T>crossProduct(const vector3d<T>&p)eonst;//叉积T getLength0 const;T getDistanceFrom(eonst//求模vector3d<T>&other)eonst;//求两点距离veetor3d<T>&normalizeO;private:T X,Y,Z;//向量单位化//向量的XYZ分量) 在三维向量类vector3d中重载了运算符“+"、“."用来实现向量加法和减法 操作,还给出了点积、叉积、向量求模、两点求距离和向量单位化等运算,可 以再实际使用中很方便的使用。 (2)矩阵(CMatrix4) 在计算机图形学中,三维世界变换最常用的矩阵是4*4矩阵。下面是矩阵 (CMatrix4)的实现,给出了实现接口。 template<classT>、class CMatrix4{CMatrix4<T>operator+(const CMatrix4<T>&other)const; CMatrix4<T>operator?(const CMatrix4<T>&other)const; CMatrix4<T>operator?(const CMatrix4<T>&other)const;void translateVect(vector3d&vect)eonst;//平移 武汉理工大学硕士学位论文void rotateVect(vector3d&vect)const; private: T M【16】;//旋转//矩阵元素>在矩阵类CMatrix4中实现了矩阵的加法、减法、两矩阵乘积、平移矩阵、 旋转矩阵等操作。在实际使用中,所声明的这些操作是远远不够的,对相机操 作就需要相机的相关矩阵操作,对纹理操作就需要纹理的相关矩阵操作。这里 不再一一列举。(3)四元数(quaternion)四元数在3D世界变换中是经常用到的,下面是给出的实现接口:class quaternion{quatemion operator+(const quatemion&other)const; quatemion operator?(eonst quatemion&other)const;//相乘float dotProduct(const quaternion&other)conSt;//点乘 //单位化quatemion&normalize0;private: float X,YZ,w;//四元数各个分量>在四元数类quatemion中给出了加法、乘法、点乘、单位化等操作。(4)平面(plane3d)一个平面可以用平面方程硝+6】,+钇+d=0来进行描述。其中可以(口,b,c)是平面的法线向量,因此一个一个平面可以由一个向量和一个常量来进行描述, 下面给出了平面的实现接口。template<class T>class plane3d{enum ERelation{ISREL3D―FRONT=0,ISI也L3D_BACK,ISREL3D PLANAR 武汉理工大学硕士学位论文);T getDistanceTo(constvector3d<T>&point)eonst;//点到平面距离ERelation pointRelation(const private:vector3d<T>&point)eonst;//点面关系veetor3d<T>Normal;//法线向量T D;//常量部分>在平面类plane3d中主要是实现了如何求点到平面距离、点平面关系等操作, 在实际应用中会经常使用到点面关系,来对场景中物体关系进行判断,因此实 现这些操作是非常必要的。3.4渲染系统3.4.1视窗模型计算机图形的要点就是创建三维物体的二维图像(图像必须是二维的,因 为它是在平面的屏幕上显示的)。但是在我们决定怎样在屏幕上绘图时,必须使 用三维坐标的方式来考虑,然后对三维物体通过模型、视图和投影变换几何变 换后显示在二维屏幕上。 相机(camera)相当于我们的眼睛,视景体(view frustum)相当于我们的 视线范围,只有出于视景体中的物体我们才能看见。视景体实质上是一个裁剪 的概念,虽然我们的计算机性能越来越高,但是随着场景越来越复杂,每一帧 需要渲染的三角形数越来越多,因此为了能够保持较高的FPS通过视景体多三 维场景进行裁剪是非常必要的。图3.1即为由相机和视景体构成的相机模型。’一近平面EI图3.1相机模型图 相机类CCameraSceneNode是用来控制相机的。控制其在空间中如何旋转、22 武汉理工大学硕士学位论文移动,设置视点、视景体等功能。class CCameraSceneNode{void setTarget(const core::vector3df&pos); void setRotation(const core::vector3df&rotation); void setUpVector(const corc::vector3df&pos); voidsetNearValue(f32蕊); zO;void setFarValue(f32 pfivme: vector3df vector3df float floatTarget;//目标点UpVector;//视景体朝向 //近裁剪点 //远裁剪点 //位置 //旋转ZNear;ZFar; position; rotation;vector3df vector3dfSViewFrustum ViewArea;};在OpenGL中我们可以使用glMatrixMode(GL_PROJECTIOFO;口-]"以对投影矩 阵进行操作,投影变换的目的就是定义视景体,即可以对投影矩阵的操作来对 视景体进行操作。3.4.2天空在绘制室外大场景时,最先需要考虑的是创建一个大背景,即天空。因此 天空是一个室外场景不可或缺的组成部分。在实际使用中,模拟天空场景的途 径主要有三种:平面天空、天空球和天空盒。天空能够使场景有层次感和真实 感。 (1)平面天空(Sky plane)是在整个场景的后端使用一张天空内容的纹理, 我们通过适当调整视角和观察点,来达到让人有一种融入场景之感。在实际使 用的时候,此方法一个明显的好处是简单,并且消耗的软硬件资源非常少,同 时明显的不足是纹理是二维平面的,逼真程度较低。在实际使用中可以用来模 拟镜头很少移动情况下的天空场景,在3D环境下已经很少使用。23 武汉理工大学硕士学位论文(2)球形天空(Sky dome)就是一个带纹理的球体模型,将摄像机(Camera) 包含在球体中心,摄像机都一直处在球体的中心,并且视点无论怎么变化都只 能看到一部分天空球。球形天空是能够逼真的模拟天空,越逼真需要使用的顶 点数越多,消耗的资源也就越多。 球形模型建立后,需要按照要求做一个球面的纹理贴图,并且将纹理贴在 模型的内侧,而球体的半径要根据相机的裁剪范围进行缩放,只有这样才能够 看到天空的景象。在实际使用中球体的中心始终要与相机的坐标重合,要不然 就会有失真出现。 (3)天空盒(Sky box)是由环绕视点的6张图所组成的立方体来包围整个场景,将摄像机(Camera)包含在立方体的中心,摄像机都一直处在立方体的中心,并且视点无论怎么变化都只能看到一部分天空盒。天空盒的本质就是六面空间 立方体,在六个面的内侧分别贴上相应的天空纹理,纹理的要求是必须能够相连,接缝处不能有缝隙。这六个面分别对应从视点或者摄像机(Camera)观察上、下、前、后、左、右六个方向天空的景象。因此简单的说渲染天空盒的本 质是渲染六面空间立方体。 天空盒实现的逼真程度取决于图片的真实度,六张纹理必须被精心设计以 使它们看起来连接得天衣无缝,应用时要忽略光照的影响,因为如果受光照影 响的话,天空盒就会有明暗,盒子的内部棱角就会有阴影,各个面的明暗差别 会非常明显,天空看上去就不会浑圆一体了。天空盒实现简单,并且也能很好 的表现出天空景观,但是它有一个缺点,那就是离天空边缘近的时候天空纹理 会有非常明显的扭曲变形。 如图所示,左边是天空盒的三维模型,右边是六幅纹理的展开图,可以看 出这六幅图片相互能够衔接在一起,而不产生接缝。然后我们通过OpenGL的 纹理映射功能,将天空图片映射到天空盒的内侧面,就可以实现天空盒。天空 盒的模型如图3.2所示:,_啊『啊甲..矿-‘?謦,。,》醪£图3.2天空盒模型图 武汉理工大学硕士学位论文球体天空盒的优点显而易见,整个模型比较平滑,能够消除立方体天空盒 在使用中出现的棱角现象。缺点也显而易见,模型较为复杂,立方体天空盒只 需要24个点就能够完成,而球形天空盒,可能需要成百上千的点。因此在嵌入 式设备上不太适合使用球形天空。在本论文中,我们使用立方体来模拟天空。 在计算机图形学中,顶点是空间中的一个点,一般由它的坐标、法线方向、 顶点颜色、纹理坐标来表示。结构S3Dvertex就是对顶点数据的一个封装。structS3DVertex{vector3d<float>Pos;//位置vector3d<float>Normal; SColor//法线方向Color;/顺点颜色//纹理坐标vector2d<float>TCoords;) 材质,通俗的讲是一个物体看起来是什么样的质地。在计算机图形渲染时 候,实质是各种属性的集合,通常包括表面的色彩、纹理、透明度、反射率、 折射率、发光度等。structSMaterial{CTexture*Texture; SColor//纹理.AmbientColor;//环境光强度 //散射光强度SColor DiffuseColor; SColorEmissiveColor;//发光度 //镜面反射强度SColor SpecularColor;} 天空盒类,它主要含有两个数据,顶点(Vertice)信息和材质(Material) 信息。rende“)方法主要是用来渲染天空盒,在每一帧重绘的过程中都会调用, 在其中会根据当前相机的位置,相机始终位于天空盒的正中心,重新确定计算 出天空盒的各个面的位置,然后将这6个面重新绘制出来。下面就是对天空盒 的定义接口和所包含的数据。6个面每个面用4个顶点表示总共24个顶点,6 个面就需要6个材质。class CSkyBoxSceneNode{25 武汉理工大学硕士学位论文void render();private://渲染skyboxS3DVertexVertices[4?6】;/颀点//材质SMaterial Material[6];};立方体天空盒渲染流程如图3.3所示:广再石]茎墼当堕塑垫二二二£二获取相机当前坐标皇获取相机远近裁剪点计算出天空盒的缩放比例二二[ 二二[ ――厂设置世界坐标系 映射纹理 绘制顶点r磊萧]图3.3天空盒渲染流程图 如图为天空盒的渲染流程,渲染是通过在每一帧调用类CSkyBoxSceneNode 的render0;方法实现的。由于相机是永远处在天空盒的,先获取当前相机的当前 位置,然后通过相机的远近裁剪距离,实际计算出天空盒应当缩放的比例,如 果不这样计算,天空盒如果处于裁剪距离外我们将什么都看不到,再设置世界 坐标系,设置顶点坐标、纹理坐标等信息,最后将设置好的顶点绘制出来。3.4.3公告板公告板(Billboard)指的是一种从始至终能够朝向观察者(或者镜头)的一 个物体。一般来说它是一个多边形,最常见的是一个矩形,在引擎内部容易进 行建模。室内室外的很多物体,例如森林、火苗、立柱等等,这些物体大都具 有非常复杂的细节,在现实中很难使用3D MAX等建模工具进行实现。所以我 们就使用这种既简单又实用的方法(Billboard)来近似模拟。 公告板技术简单的说就是把一幅二维纹理图片贴在一个多边形上,在实时 渲染过程中,根据镜头的位置实时计算出多边形应当旋转的角度(可以围绕点 进行旋转也可以围绕旋转轴进行旋转),以保证多边形始终能够面向镜头。在本 武汉理工大学硕士学位论文文中就是采用的矩形来对Billboard进行建模的。在引擎中矩形只需要4个顶点 就能够进行建模,将4个点连成一个矩形面,然后将我们所需的物体(二维纹 理图片)贴在这个矩形面模型之上。接下来比较关键也是Billboard的核心问题 就是怎么样实现让这个四边形一直朝向观察者(镜头)。矩形的中心就是这个矩 形面模型的中心,我们选取通过中心与矩形面平行的一条旋转轴作为billboard 的旋转轴,它的法向量是通过中心垂直于矩形面的一个向量,然后就可以根据 镜头位置的不同设置矩形面的旋转角度,使它的法向量始终是指向镜头的,从 而能够始终面向观测者(镜头)。公告板模型如图3-4所示:因、甲,购 \\l/\|/'’视点 、’j{,么图3_4公告板模型图 公告板(billboard)在实际使用中还结合Alpha融合技术,使得矩形面本身 是不可见的,只是将图像有用部分显示出来即可。使用这种方法建模,能够依 据视线的旋转而旋转,始终能够保证观察者(镜头)看到的是物体的正面,既 能够降低硬件的开销又能够很好的表现物体的细节。 公告板类CbillboardSceneNode,有三个数据,公告板的大小,材质,顶点。 用4个顶点建立一个矩形,矩形的大小由size来确定,然后将纹理图片贴在这 个矩形之上即可为公告板,在每一帧重绘的时候根据公告板和相机的关系,计 算出公告板的旋转角度,始终让公告板朝向镜头。class CBillboardSceneNode{virtual void render0; private: dimension2d<f32>Size;SMaterial Material;S3DVertexvertices[4];27 武汉理工大学硕士学位论文>;如图,为CbillboardSceneNode类中render();方法实现的先是根据相机坐标 和朝向计算出相机的视线向量View,然后和视景体朝向UpVector叉乘计算出公 告板的水平方向向量H,H与View叉乘得出公告板垂直方向的方向向量V,然 后根据公告板中心的坐标即可求出公告板平面,在根据公告板的大小Size就可 以求出公告板四个顶点的坐标,设置纹理映射关系,最后将其绘制出来。过程 看似简单,实际用到了向量的相关算法,由于对相关数学方法进行了有效的封 装,在后面使用中就非常容易。因此在三维引擎中对计算机图形学方面的数学 计算进行封装可以有效的减少后续开发的难度。公告板渲染流程如图3.5所示:。.£翌J粼吾3.5粒子系统一V錾一_ _图3.5 Billboard渲染流程图在自然界中大部分的景象都是包含丰富的或者随机实时变化的形状,这种 形状很难用普通的解析曲线曲面来进行描述。例如火、爆炸、烟、水流、火花、 落叶、云、雾、雪、尘、流星尾迹或者发光轨迹这样的抽象视觉效果等等。 通常人们都是采用图片叠加的方式来实现对火苗、雨、雪等自然现象进行 模拟的,其效果可想而知较差,不仅需要大量的图片素材,而且对硬件的要求 非常高,很难满足逼真度的要求。 1983年Reevs提出了一种模拟不规则模糊物体的方法粒子系统方法,该粒 子系统方法的主要优点是可以利用非常简单的粒子来构造复杂的物体【38】。它为自然场景――云、火苗、雨和雪等3D复杂自然景物的造型提供了非常强有力的28 武汉理工大学硕士学位论文技术保证。3.5.I粒子系统原理粒子系统的本质是将大量相似或者相同的很小的粒子图像按照设定好的规律组合起来用来描述和模拟不规则或者模糊感的物体。在实际使用中,雨雪的模拟、流水的模拟、火焰的模拟等都离不开粒子系统。粒子系统是一种过程模型,即利用各种计算过程产生模型各个要素的建模技术。一般情况下,粒子的几何特性可以采用一个小的多边形来表示,通常是一个带有纹理的四边形。可以认为粒子是一个有四个顶点的三维模型,映射不 同的纹理将可以模拟不同的粒子效果,在模拟自然界时候, 大多数是过程化的,‘必须要加入随机化的控制方式,即粒子的产生时,粒子的位置、运动方向、大小、初始颜色等都是随机的。当我们绘制粒子的时候,其实就是绘制多边形, 一个粒子其实就是一个带有纹理的四边形。如图3.6所示是一个4个单位大小的粒子模型。+o点/2●位。/图3-6 4单位大小粒子示意图粒子系统中的每个粒子具有一组确定的属性:生命期和状态属性。状态属 性一般包括:位置、大小、形状、颜色、透明度、运动速度等。一个粒子究竟 有什么样的属性,主要取决于具体的应用。为了台皂够有逼真的效果,粒子属性值的初始值一般是通过随机过程产生的。通常我仃丁把粒子系统分两个部分:粒 子发射器和粒子影响器。粒子往往通过位于空间某个位置的粒子发射器产生,然后通过粒子影响器随时间不断变化粒子的属性值的,从而逼真的模拟不规则物体。在粒子系统中,每一个粒子在生命周期内都要完整的经历产生、动态改变、 死亡三个阶段,粒子通过粒子发射器产生,通过粒子影响器动态的改变其状态, 当粒子生命周期结束后将粒子删除,图3.7是粒子周期流程图: 武汉理工大学硕士学位论文图3.7粒子周期流程图(1)粒子发射器产生粒子并且进行初始化,每秒钟产生一定数目的粒子, 其初始属性值通过随机过程控制。每个粒子的生命周期可以是一个固定值,如果某些粒子一直存在不应该被删除,则生命期可以是无限长的。(2)粒子影响器更新现有粒子的属性,如,若粒子有位置和速度属性,就需要根据粒子原来的位置、速度和流逝的时间计算粒子的新位置。(3)删除已经“死亡"的粒子,在粒子系统中,检查所有粒子的生命期, 如果发现粒子生命期为零或者其他死亡条件,就可以将粒子从粒子系统中删除掉。这样可以很好的节约我们宝贵的硬件资源。(4)绘制粒子,将粒子系统中所有存活的粒子绘制出来。通常我们采用的 渲染技术是公告板技术(Billboard)来渲染单个粒子,粒子始终是朝向镜头的。 3.5.2基于粒子系统的雪景设计 在自然界中下雪是很常见的天气现象,对雪景的模拟是我们模拟自然现象 的一个非常重要的方面。模拟雪花的时候,我们可以使用一个粒子来代表一个 雪花。雪花在空中飘落的时候形状不尽相同,雪花飘落时候,受重力和风力影响,整体方向是向下,但是会随着风向到处飘落。根据前面的叙述,粒子的属性一般有:粒子位置、生命周期(创建时间, 死亡时间)、运动速度(初速度,当前速度)、粒子外观(大小,颜色)等。 (1)粒子位置属性。在嵌入式系统中为了考虑系统的硬件限制,提高显示 帧率。因此我们是将雪花的显示范围尽量压缩在一个一定的区域内的,最简单 的一种方法是将雪花的范围放在一个立体的盒子中,通过随机函数来确定这个 雪花处在这个盒子的什么位置,假设position[i】为第i个粒子的初始位置, MinEdge,MaxEdge分别表示立体盒子的最小坐标值和最大坐标值点。则有以下计算公式如(3.1)所示。30 武汉理工大学硕士学位论文(3一1) l l=MinEdge+Rand(MaxEdge―MinEdge) 在这里RandO是一个均匀分布的随机函数,它的取值范围是position f(拖x嗽P―M切勘船)之间,position[i].而position[i].y,position[i].z分别用来表示函Y,z坐标。(2)粒子外观属性。外观属性包括大小和颜色。为了能够更加逼真的模拟 下雪的场景,雪片的大小是可以有适当的变化的,但是不能超出正常范围。因 此使用随机函数来对粒子的大小进行控制。对于雪我们一般都是纯白色的,这 一项对雪景模拟设置为(R,G,B,A)=(1.o,1.o,1.0,1.o)。 (3)生命周期属性。粒子的生命周期是指粒子存在的寿命时间,因此会在 初始化的时候赋予粒子生成的时间和粒子死亡的时间,在死亡时间之前粒子是 存活的。当到达死亡期后就应当将粒子进行删除。 (4)运动速度属性。运动速度主要是指雪花粒子的初始速度,速度是有大 小和方向的因此是用向量进行表示和计算的。如(3.2)所示:InitialSpeed=MinSpeed+RandOxVarSpeed(3―2)当粒子生成,初始化完成后,对其状态进行影响的主要就有两个方面重力 和风向,我们知道力是可以合成的,因此我们在设计粒子影响器的时候不必去分别设置重力影响器和风力影响器,用一个合成影响器来进行模拟即可,这样 可以加快运行速度。在三维空间中根据牛顿力学运动规律,雪花的运动模型可以表示为如(3.3)所示 y=虼4-b dt,S=so+h,dt(3―3)3.5.3基于粒子系统的雪景实现粒子系统的职责是负责管理模拟现实世界简单粒子集合的一个实体,通常的功能有添加粒子、删除粒子、更新粒子属性等等。在我们实际使用中粒子系统又可以分为两个部分粒子属性管理和粒子外部作用管理。因此在实现粒子系统的时候我们可以将系统分为两个组件:粒子发射器和粒子影响器。粒子发射 器主要用来生成粒子并设置其初始状态值,可以是位置、生命周期、运动速度、 外观。粒子影响器主要是用来更新粒子的状态、形态等等,决定了粒子在空间 中是如何运动的以及运动轨迹。在实际使用中,粒子发射器可以分为盒子发射 器、圆形发射器、点发射器、环形发射器。粒子影响器又可以分为重力影响器、渐出影响器、缩放影响器。3l 武汉理工大学硕士学位论文在雪景粒子系统中,我们使用的是盒子发射器和重力影响器。其系统组成框图如图3.8所示:图3.8雪景粒子系统组成框图粒子的主要属性有:空间位置、生命周期(创建时间,死亡时间)、粒子夕卜观(颜色,大小)、运动速度(大小,方向)。存储粒子属性的数据结构如-V:struct SParticle{vector3dfpos; u32 startTime; u32 endTime; SColor color;’//粒子位置 //粒子创建时间 //粒子死亡时间//粒子颜色(顶点颜色)//粒子初始速度和方向 //粒子当前速度和方向vector3dfstartVector; vector3dfvector;dimension2dfstartSize;//粒子初始大小 //粒子当前大小dimension2df size;};盒子发射器 (CParticleBoxEmitter),重力影响器(CParticleGravityAffector), 粒子管理为了实现雪景粒子系统, 我们需要3个类:(CParticleSystemSceneNode)。粒子管理主要实现将粒子发射器和粒子影响器有机结合起来,首先按照当前系统时间更新发射器和影响器,然后读取粒子列表,检查每一个粒子的是否已经死亡,如果死亡将其从列表中删除,将未死亡的添加到渲染歹IJ表中去,最 后将渲染列表中的粒子属性生成相应的Billboard渲染输出。其流程图如图3―9所示:32 武汉理工大学硕士学位论文图3-9粒子管理流程图 粒子发射器主要是用来生成粒子并设置其初始状态值,通过随机函数生成 粒子位置、生命周期、运动速度、外观等属性。最后将生成的粒子加入到粒子 列表中进行存储。其流程图如图3.10所示:r并万]读取系统时间.计算本帧需要发射粒子数N通过随机函数产生粒子坐标 通过随机函数产生粒子初始速度初始粒子大小和颜色将粒子属性数据存储到列表中 初始粒子生成时间和死亡时间 初始粒子大小和颜色茹秽! Y:成完毕?/葡图3.10粒子发射器流程图 粒子影响器主要是用来更新粒子的状态、形态等等,决定了粒子在空间中 是如何运动的以及运动轨迹。重力影响器是将重力向量与粒子初始速度向量按 照差值系数进行差值得到当前粒子的速度,然后可以将速度和流逝的时间相乘近似的算出位移,最终在计算出粒子的当前位置。其流程图如图3.1l所示: 武汉理工大学硕士学位论文墓3.5.4粒子系统改进算法将流逝的时问值与当前速度值 相乘近似计算其位移零图3.11粒子影响器流程图粒子系统的本质是将大量相似或者相同的很小的粒子图像按照设定好的规 律组合起来用来描述和模拟不规则或者模糊感的物体。因此在实际中即使是在 一个很小的区域内,所使用的粒子数目也是相当可观的,前文中所使用粒子系 统算法对存储和计算速度都有相当大的要求,而嵌入式设备所稀缺的也是存储 空间和CPU的计算能力,因而在本文中对粒子系统的算法做了一些优化和改进,以改善场景渲染的帧率。 (1)简化物理模型在粒子系统中,雪景、雨景的模拟,都离不开对重力场等物理模型的模拟。前文中提到的积分的运算量相当的大,不利于在嵌入式设备上使用,因此简化了物理模型,使用离散的物体运动模式。算法如下: 在生命周期内,设粒子的加速度恒定,所以粒子的速度只与初始加速度有关。每一帧的只有*lid,的时间间隔,因此我们可以将两帧间的运动看做是匀速度的运动,粒子速度和位置的运算公式(3.3)可以变形为如(3-4)所示:圪=K―l+aT.-l,瓯=最一I+圪瓦(3-4)其中,V。表示第n帧的速度,Tn表示第n.1帧到n帧的时间,Sn表示第n 帧的位移。由公式看出匀加速运动的运算非常简单,计算量很少。 (2)改进死亡粒子处理算法 粒子进入死亡期之后,传统的做法是马上删除掉粒子所占有的空间,重新 生成新的粒子,在这个过程中可以看出,有一次内存的释放,有一次内存的申 请。而粒子一般都是采用数组来进行存储,如图3.12,假设有N元素的数组,要删除第M(M<N),那么第M+l到N元素都要向前移动,最差情况,当M=0 武汉理工大学硕士学位论文时,要移动N.1元素。粒子系统中粒子的寿命一般很短,这样也就是会有大量 的内存申请和释放,同时伴随着有数组数据的移动,这样频繁操作势必加大了 系统开销,降低了场景渲染的帧率,影响实时性。[[口……田……口’图3.12粒子存储模型本文中采取的策略是先不删除死亡的粒子,新粒子生成后,用新粒子的属 性赋给死亡粒子,若新生成粒子数目少于死亡粒子数目,则删除多余死亡粒子; 若,新生成粒子数目多于死亡粒子数目,则直接将其扩充在粒子数组之后。这 样的优点是: (a)省去了大量的申请与释放内存等非常耗时的操作。 (b)减少非死亡粒子在数组中的移动次数。本算法每次都是从数组头部扫 描死亡粒子,用新粒子属性赋给死亡粒子,这样可以尽量避免删除数组头部的 元素,而删除头部元素是最耗时的操作,减少了其他元素的移动次数。 本改进算法在很大程度上提高了程序渲染的帧率,提高了实时性。3.6文字显示系统文字是人类用来记录语言的符号系统,其本质是图形符号。字体是指一组 可以显示和打印的多样的字符映像,一般来说需要包含两个要素:字符的图像 信息和字符编码到这些图像信息的映射。从设计的原理上来说,目前使用的字 体主要有三种:点阵字体、向量字体、曲线字体。 现在,曲线字体是使用最多的,曲线一般是使用二次或者三次曲线函数来 对字体的轮廓进行描述,使用最广泛的是Adobe公司的Typel字体库和微软苹 果共同开发的True typet39】字体库。曲线字体不仅很好的改良了文字显示效果, 同时可以降低存储空间,并能够实现自由缩放而不出现失真、锯齿等现象。3.6.1 FreeTypeFreeType是一个用C语言实现的字体光栅化制作的一个函数库。我们可以 用它来将字符光栅化并映射成位图供其他业务使用。FreeType遵循BSD许可证, 因此它可以被使用在任何类型的项目中,无论是否是专有软件。FreeType支持 武汉理工大学硕士学位论文的字体格式有:TrueType,OpenType,Typel,CID,CFF,Windows FON/FNT,X11PCF等。3.6.2FreeType主要接口介绍(1)FreeType库初始化 简单地创建一个FT Library类型的变量,例如library,然后调用函数FT_Init_FreeType(FT--Library ?alibrary);这个函数返回一个错误代码,如同FreeType API的大部分其他函数一样。 值为0的错误代码始终意味着操作成功了,否则,返回值指示错误,library设为NULL。(2)装载字体face●从一个字体文件加载字体应用程序通过调用FT New Face创建一个新的face对象。一个face对象描述了一个特定的字样和风格。FT_New』ace(FT_LibraryFT_Long FTlibrary,const char*filepathname,face_index,丌_Face?aface);NEWFace打开一个字体文件,然后设法从中提取一个fa

我要回帖

更多关于 opengl es 视频教程 的文章

 

随机推荐