基于OpenGL水波模拟-本科毕业论文_第1页
基于OpenGL水波模拟-本科毕业论文_第2页
基于OpenGL水波模拟-本科毕业论文_第3页
基于OpenGL水波模拟-本科毕业论文_第4页
基于OpenGL水波模拟-本科毕业论文_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PAGE论文题目:基于OpenGL的水波动画模拟系别:______计算机系_PAGEIIWavesimulationbasedonOpenGLCollege:SpecialtyandGrade:Number:Name:Advisor:Submittedtime:May7,20

目录TOC\o"1-4"\h\z\u311131.1课题提出的背景 322011.1.2课题的意义 3293451.2国内外研究现状 394901.2.1四大类水波模拟的方法 3229331.2.2水波模拟面临的困难 4164391.2.3国内水波动画模拟相关研究 422331.2.4国外水波动画模拟相关研究 524366第二章基于OpenGL+MFC建模基础 772522.3OpenGL渲染管线 8291902.3.1显示列表 875392.3.2求值器 8229922.3.3基于顶点的操作 9236082.3.4图元装配 951752.3.5像数操作 9157492.3.6纹理装配 9248092.3.7光栅化 980022.3.8片段操作 959812.4计算机图形学 10203612.3MFC框架 10224572.4基于OpenGL+MFC的三维模拟的编程环境配置 1213951第三章水波的计算机模拟原理和关键技术 14224933.1水的流体物理性质 1440033.2基本原理 16219883.2.1建立区域采样法水波数学模型 16140353.2.2水波扩散分析及解决方法 1617311第四章基于OpenGL的水波模拟 17282594.1系统设计 1768574.2水波模拟的算法设计 17284054.3扰动 2120584.4水波模拟系统的逻辑视图 21222534.5主要结构体和类的设计: 23192154.5实验结果 2432443第五章结论与展望 27236005.1结论 2782795.2展望 2711392参考文献 28PAGE33摘要近年来,自然景物的模拟一直是计算机图形学最具挑战的问题之一,关于山、水等自然景物的模拟,在计算机游戏、影视、广告各领域中有着广泛的用途,作为自然景物模拟的重要内容,对水流、水波的模拟正日益引起人们的关注.。本论文通过对国内外水波动画模拟的相关成就的介绍,与对其的一定了解和文献的参考,基本实现了水波的模拟,基于opengl+MFC建模基础展开探讨,对水波的计算模拟原理和关键技术进行阐述,例如水波的物理模型,运动方程,物理特性等,结合以上知识进行水波模拟,实验证明该方法实现简单,模拟的水波动画效果满足实时性和逼真性的要求。关键词:水波模拟;物理模型;opengl;运动方程;

Abstract:Inrecentyears,theimpersonationofnaturallandscapehasbeenacomputergraphicsthemostchallengingproblems,oneofthehills,watersandnaturalscenery,incomputergames,advertisingfilm,theareahasanextensiveuseofnaturalsceneryasanimportantpartofasimulationofthewater,waterwasincreasinglyacauseforconcern.Thispaperwithanimatedsimulationswaterthroughtheachievementofitsintroduction,andbesuretounderstandandthereference,thewater,basedonthemodelingopenglmfcbasedonthewater,theimpersonationandthekeytechnologies,suchaswaterphysicalmodel,theequationofmotion,physicalproperties,etc,themoreknowledgeonthecorrugated,experimentsprovethismethodtoprocessofanimation,theeffectofwatercontenttimelyandaccuratesexualKeywords:thecorrugated;thephysicalmodelstosimulate;opengl;equationofmotion;

第一章绪论OpenGL是由SiliconGraphics公司推出的一种高性能图形开发软件工具包,该工具包括大约120条不同的指令,它独立于硬件,独立于窗口系统,由于具有这个优越的特性,因此可以运行于各种操作系统,而且可以在各个平台之间进行移植,并且能在网络环境下以客户/服务器模式工作,已经成为专业图形处理、科学计算等高端应用领域的标准图形库,因此Microsoft,SGI,IBM等在计算机市场中占主导地位的大公司都用它作为自己的标准图形库课题提出的背景通过计算机尽可能逼真的模拟现实世界,一直是计算机图形学,特别是虚拟现实技术的一个研究热点。对于地形的绵延起伏、光的折射和反射等自然现象的模拟,人们可以根据一些现有的不太复杂的数学公式,通过数学建模来获得某种特定的效果。但是对于另外一些自然现象,例如各种烟雾,水,火焰等流体现象,虽然看似简单,但是对其进行描述的物理模型却极其复杂,这时只有去追溯该现象本身的物理根源,并借助更为精确的物理描述才能真实再现其外在的视觉效果。水波模拟不仅是一个很具有挑战性的研究课题,更具有很好的商业价值,它在航海仿真、虚拟城市游览、视频游戏、数字电影和数字广告中都有大量应用。一片逼真自然的水面可以很好的增加场景的逼真感和沉浸感。目前的一些三维图形软件产品已经有不少包含了流体模拟的模块,如Maya里面的MayaFluidEffectsTM;3DSMax提供的glu3D流体插件;NextLimit推出的RealFlow和RealWave独立软件包更是出类拔萃,被称为PC机上最好的两种流体动力学模拟软件。但是他们只是流体的图形建模工具。1.1.2课题的意义从一杯纯净的清水到潺潺的小溪,从微波起伏的湖面到巨浪滔天的海洋,这些日常生活中看似十分平常的东西,在计算机图形学和虚拟现实技术研究者的眼中看来,与模拟地形、雨雪等其他自然景观相比较,模拟流体更具有挑战性。究其原因,主要流体的形体多变,没有一个固定的形状,很难用一个通用的方程来表示;物理模型极其复杂,其波动是受到重力、摩擦力、粘滞力等各种力的综合影响;力学方程的数学表达式多为偏微分方程,求解难度大,计算复杂;具有复杂的光学效果,如水的透明度、折射和反射等。虽然具有挑战性,但方法总比问题多。早期我们使用波形函数模拟简单的水面波动,随着计算机硬件水平的发展和研究技术的进步,如今可以根据流体的物理模型,使用数值方法模拟真实感很强的三维流体。近年来,计算机图形学的发展突飞猛进并有着极为广泛的用途.计算机图形学的发展使得三维表现技术得以形成,所谓计算机三维图形就是指将用数据描述的三维空间通过计算转换成三维图像并显示或打印出来的技术,OPENGL就是支持计算机三维图形的一个程序库.在计算机图形学中,模拟水流动画是一个很有意义的课题.1.2国内外研究现状1.2.1四大类水波模拟的方法目前水波动画的模拟方法大体上可以分为四大类:第一类:基于波的分析方法。这类方法直接构造参数曲面来代表水表面,参数曲面由波形函数表示,也就是说这一类方法通过直接模拟波属性来得到水波的水波图像,可以模拟雨点造成的水波,微风造成的涟漪和紊乱的短波峰,但是解决不了水流的形体的破碎问题.第二类:基于物理模型的方法。基于物理模型的基本思路是用物理规律约束物体的运动,然后用图形学方法把物体形状渲染出来,这种方法可以保证物体的动态逼真性,也可以轻松地制作出逼真的动画来,这方面的典范是Navier-Stokes方程.它有很强的物理背景,是当今非浅性科学研究中的重点和热点问题.若使用这种方法建立浅水波模型,再使用计算流体动力学的数值分析工具来求取方程数值解,这个方法过于复杂且对光影处理能力差.第三类:基于粒子系统的方法,这类方法把流体看作离散的粒子集,粒子有一定的属性,使用这种方法人们成功地描述了瀑布、喷泉、水滴以及浪花飞沫..第四类:基于光影处理的方法。这类方法专注于模拟水流的光影特效,能出色地模拟人们从水底和水上观察阳光照射在水波上形成的光与影现象.这方面的工作把注意力集中到如何模拟光线和水流的作用效果上来,无法兼顾水流的其他特性.1.2.2水波模拟面临的困难水波有一系列特性,如扩散、衰减、折射以及反射等,我们需要了解这些特性以及我们所面临的问题,我们所面临的问题主要有:(1)对波的模拟,水波是水流运动的关键属性,当水流受到各种外部及内部物体的作用时,会产生波,并且在水流内部传播,视觉上表现为水表面上的波纹和漩涡;(2)光与影的处理,水是透明的,它的视觉印象很大程度上取决于周围的环境,另外水对光的折射作用使水中的光影效果复杂多变;(3)水流形体的绘制,水的形状是不确定,易于改变,一方面,若把水的形状看成一个高度场表示的曲面,则无法表现水流的破碎以及卷曲的波纹,另一方面若把水看成由许多水粒子组成的点集,又面临如何进行可视化的问题;(4)水流与外界物体的相互作用,当一个物体掉入水中或水内有物体在运动水流会受到怎样的影响1.2.3国内水波动画模拟相关研究上述的水面模拟方法都有一个共同的不足,那就是不能描述水体的自由流动和水面的剧烈变形,如波浪破碎等。为了克服这种缺陷,有研究者提出了采用粒子系统的方法来实现,但是毕竟真实感还是不够。随着计算机处理能力的增强和计算流体动力学的广泛应用,以及对模拟结果真实感的追求,近年来国内外对流体模拟的研究都转向了基于物理的流体模拟,因为基于物理方法所得到的试验结果,相对于基于参数建模方法所得到的结果,不仅真实感要好上许多,而且可以实现流体表面的自由流动和剧烈变形效果,如流体飞溅,表面破碎,以及泡沫等,这是后者所难以企及的。基于物理的方法主要分为两种:一种是基于网格的欧拉法,它从研究流体所占据的空间中各个固定点处的运动着手,分析运动流体所充满的空间中每一个固定点上流体的速度、压强、密度等参数随时间的变化情况,以及研究由某一空间点转到另一空间点时这些参数的变化情况;另一种方法是基于粒子方法的拉格朗日方法,研究流体中某一指定微团的速度、压强、密度等描述流体运动的参数随时间的变化情况,以及研究由一个流体微团转到其他流体微团时参数的变化情况,以此建立整个流体的运动仿真。虽然我国计算机图形学和虚拟现实技术的研究起步晚于欧美发达国家,但是近年来国内虚拟现实技术,特别是视频游戏的快速发展,促进了我国水波模拟研究和技术的进步,也取得了很多的成绩。杨怀平根据小振幅波理论文献[1]中,水波的波形近似成正弦分布这一理论并结合细胞自动机的模型,采用邻域传播的思想对水波进行动态建模,可以构造出不同邻域下水波演变的细胞自动机模型。并且采用以POINT图元为基本粒子的粒子系统,对水花效果进行实时的模拟。为将水波和浪花逼真地结合在一起,作者运用色彩融和的技术来完成浪花的显示。实践证明用该算法模拟水波,既不需要特意构造具体的波形函数,也不用求解复杂的纳维一斯托克斯方程,就能够在普通的PC平台上实现效果比较真实的水面模拟。夏青利用柏林噪声函数生成的高度场为海浪中的每个顶点提供高度采样源,同时针对海浪仿真中计算机量大的问题,又提出一种实时绘制可见梯形范围技术,解决海浪仿真中数据量大的问题,确保实时仿真和逼真的视觉效果,同时使用菲涅尔效果,将反射和折射效果混合在一起,增强海浪起伏的真实感。王胜正在以往水波模型研究的基础上,根据海浪的形态,充分考虑各种随机参数,建立一个高性能的基于统计模型与FFT的波浪生成方法,模拟船舶在海浪中航行的各种特殊效果。李苏军采用Gerstner-Rankine模型,引入概率统计思想,借鉴了映射网格的方法,采用视点相关的圆形网格,代替传统的普通网格完成水面高度场的采样,且能支持实时动态连续分辨率水波表现的建模和绘制。邱捷利用水波物理模型模拟海面运动,该方法实现简单,而且拥有良好的性能,适合于三维游戏引擎。赵鹏,张立朝等另辟新径,在优化算法的同时,重点对规则水波模型算法进行了研究,采用计算和显示分开的策略,预先产生大量水波数据予以保存,然后在渲染时再调用这些数据实现了三维规则水面波浪的绘制与仿真,该方法的优点是既满足显示质量的要求,又满足实时性要求,但由于波浪数据是预先生成的,没有考虑随机扰动等外界干扰。1.2.4国外水波动画模拟相关研究技术发达的欧美国家很早就开展了对海洋和湖面这类广域水面水波模拟的研究,也一直走在流体模拟研究的前列,很多新颖的模拟方法都是由国外学者提出来的。早期水波模拟方法主要采用参数建模方式,通过直接构造参数曲面来表示水面。早在1809年Gerstner[1]提出了GerstIler模型用于海浪建模,采用波函数来模拟海面高低起伏的运动。1863年Rankine又对这一模型进行改进和完善,后人称之为Gerstner-Rankine模型。概略地讲,这一模型描述沿圆形或椭圆形固定轨道运转的水粒子。由表面中的每一个粒子沿着其静止位置点作圆周运动。假设海平面静止时是XY平面,Z轴指向朝上,一个粒子的运动方程为:(1-1)(1-2)该方法不需要大量的网格转换计算,但需要合理地调整参数和添加一些背景噪声。为增加逼真度,Gerstner-Rankine模型往往采用叠加不同频率的波形函数和增加网格顶点方法,因此计算量也随之增大,另外一个不足之处是对于不同的波形需要重新定义不同波形函数,缺乏通用性。快速傅里叶变换(FastFoumierTransformation,FFT)可实现时域到频域的变换,在很多领域有广泛的应用。Jensen[2]、Tessendorf[3]、FredrikLimsater[4]分别详细描述了利用海洋统计和经验模型,通过FFT合成一个类似海浪谱分布的高度场模拟海浪的方法,此方法的模拟的海面场景是目前参数法当中真实感是最强的,也是当今运用最广泛的水面建模方法。相信很多人都看过“泰坦尼克号"和“新海神号历险记”这两部电影,对电影中那铺天盖地的海水吞没泰坦尼克号和海神号时的场景肯定印象深刻。其实那些海水都是使用快速傅里叶变换的方法模拟出来的。但由于在合成过程中常采用规则矩形粗网格来完成实时绘制和避免FFT方法产生的视觉上明显的重复性,从而降低了图像的质量和真实感。另一个不足之处就是因为流体表面的网格点只能在其起始位置附近运动,无法模拟波浪破碎和水沫效果。需要借助粒子系统解决,将粒子系统放在水面与岸相撞击的地方,以粒子来模拟浪花和泡沫,提高模拟的真实感。海洋统计学研究指出,海面波浪的起伏运动是一个服从正态分布的随机过程,而且具有各态历经性,因此服从高斯分布的噪声函数开始在大规模水面模拟中得到了广泛的应用。1985年Perlin提出柏林噪声函数。该函数是能够在空间中产生连续噪声的函数。通过叠加不同层次的噪声函数可以很好的模拟自然现象中的分层现象,在地形生成[5],立体云模拟[6]和水面模拟当中应用广泛。在水面模拟当中可通过柏林噪声函数来构造海面高度场,模拟水面的随机起伏,例如Johanson[7]引入投影网格的概念,在后透视空间构造海面网格,并通过Pedin噪声的叠加来构建海面高度场。LawrenceM.Lachman[8]则借鉴了LOD这一有效的场景管理方式,提出了一种多层次开放式结构对海水进行建模,通过使用多层次多分辨率方法在GPU上实现海浪模拟,提高了渲染速度。海面波浪的运动具有一定的物理规律,因此基于物理模型的海洋模拟是近年来海面模拟的一个研究热点。SimonPremoze[9]提出了一种新的基于物理模型的大面积水面(如海面,湖泊水面)产生方法,作者根据海洋学的观察数据实时生成波浪,并且通过几个简单又具有物理意义的参数,如风速,风向来控制波浪。同时还考虑光在水中传播的物理特性,在不同天气环境和光照下,水体也呈现不同的颜色,最终的模拟效果十分逼真。随着可编程GPU的出现,GPU的运用已不仅仅是3D加速和渲染,已经有很多研究者开始利用GPU的强大计算能力来加速计算。针对FFT计算量大的缺陷,JasonL.MiteheU[10]提出了一种基于GPU的傅里叶域多边带(multi.bandFourierdomain)方法,模拟了广袤海洋场景。

第二章基于OpenGL+MFC建模基础2.1OpenGL简介OpenGL(全写OpenGraphicsLibrary)是个定义了一个跨编程语言、\o"跨平台"跨平台的\o"编程接口"编程接口(Applicationprogramminginterface)的规格,它用于生成\o"二维计算机图形"二维、\o"三维计算机图形"三维图像。这个接口由近三百五十个不同的函数调用组成,用来从简单的图元绘制复杂的三维景象。而另一种编程接口系统是仅用于\o"MicrosoftWindows"MicrosoftWindows上的\o"Direct3D"Direct3D。

OpenGL常用于\o"CAD"CAD、\o"虚拟实境"虚拟实境、科学可视化程序和\o"电子游戏开发(尚未撰写)"电子游戏开发。OpenGL的高效实现(利用了图形加速硬件)存在于\o"MicrosoftWindows"Windows,很多\o"UNIX"UNIX平台和\o"MacOS"MacOS。这些实现一般由显示设备厂商提供,而且非常依赖于该厂商提供的硬件。\o"开放源代码"开放源代码库\o"Mesalibrary"Mesa是一个纯基于软件的图形API,它的代码兼容于OpenGL。但是,由于许可证的原因,它只声称是一个“非常相似”的API。OpenGL规范由\o"1992年"1992年成立的OpenGL架构评审委员会(ARB)维护。ARB由一些特别兴趣于建立一个统一的普遍可用的API的公司组成。根据OpenGL官方网站,\o"2002年"2002年\o"6月"6月的ARB投票成员包括\o"3Dlabs"3Dlabs、\o"苹果公司"AppleComputer、\o"ATI技术公司"ATITechnologies、\o"戴尔"DellComputer、\o"Evans&Sutherland(尚未撰写)"Evans&Sutherland、\o"Hewlett-Packard"Hewlett-Packard、\o"InternationalBusinessMachines"IBM、\o"Intel"Intel、\o"Matrox"Matrox、\o"NVIDIA"NVIDIA、\o"SiliconGraphics"SGI和\o"SunMicrosystems"SunMicrosystems(\o"Microsoft"Microsoft曾是创立成员之一,但已于\o"2003年"2003年\o"3月"3月退出)。2.1OpenGL发展历程1992年7月,SGI公司发布了OpenGL的1.0版本,随后又与微软公司共同开发了WindowsNT版本的OpenGL,从而使一些原来必须在高档图形工作站上运行的大型3D图形处理软件也可以在微机上运用。1995年OpenGL的1.1版本面市,该版本较1.0性能提高许多,并加入了一些新的功能。包括提高顶点位置、法线、颜色、色彩指数、纹理坐标、多边形边缘标识的传输速度,引入了新的纹理特性等等。1997年,Windows95下3D游戏的大量涌现,游戏开发公司迫切需要一个功能强大、兼容性好的3D图形接口,而当时微软公司自己的3D图形接口DirectX3.0功能却是很糟糕。微软公司最终在Windows95的OSR2版和后来的Windows版本中加入了对OpenGL的支持。这样,不但许多支持OpenGL的电脑3D游戏得到广泛应用,而且许多在3D图形设计软件也可以运用支持OpenGL标准的3d加速卡,大大提高其3D图形的处理速度。2003年的7月28日,SGI和ARB公布了OpenGL1.5。OpenGL1.5中包括OpenGLARB的正式扩展规格绘制语言“OpenGLShadingLanguage”。OpenGL1.5的新功包括:顶点BufferObject、Shadow功能、隐蔽查询、非乘方纹理等。2004年8月,OpenGL2.0版本发布~OpenGL2.0标准的主要制订者并非原来的SGI,而是逐渐在ARB中占据主动地位的3Dlabs。opengl2.0支持OpenGLShadingLanguage、新的shader扩展特性以及其他多项增强特性。2008年8月初Khronos工作组在Siggraph2008大会上宣布了OpenGL3.0图形接口规范,GLSL1.30shader语言和其他新增功能将再次未来开放3D接口发展指明方向。OpenGL3.0API开发代号为LongsPeak,和以往一样,OpenGL3.0仍然作为一个开放性和跨平台的3D图形接口标准,在Shader语言盛行的今天,OGL3.0增加了新版本的shader语言:GLSL1.30,可以充分发挥当前可编程图形硬件的潜能。同时,OGL3.0还引入了一些新的功能,例如顶点矩阵对象,全帧缓存对象功能,32bit浮点纹理和渲染缓存,基于阻塞队列的条件渲染,紧凑行半浮点顶点和像素数据,四个新压缩机制等等。OpenGL仍然是唯一能够取代微软对3D图形技术的完全控制的API。它仍然具有一定的生命力,但是SiliconGraphics已经不再以任何让微软不悦的方式推广OpenGL,因而它存在较高的风险。游戏开发人员是一个有着独立思想的群体,很多重要的开发人员目前仍然在使用OpenGL。因此,硬件开发商正在设法加强对它的支持。Direct3D目前还不能支持高端的图形设备和专业应用;OpenGL在这些领域占据着统治地位。最后,开放源码社区(尤其是Mesa项目)一直致力于为任何类型的计算机(无论它们是否使用微软的操作系统)提供OpenGL支持。08年8月正式公布OpenGL3.0版本。并且得到了nv的支持,其官方网站上提供针对N卡的sdk下载。2.3OpenGL渲染管线绝大数OpenGL实现都有相似的操作顺序,一系列相关的处理阶段称为OpenGL渲染管线。图1显示了这些顺序,虽然并没有严格规定OpenGL必须采用这样的实现,但它提供了一个可靠的指南,可以预测OpenGL将以什么样的顺序来执行这些操作。图1OpenGL渲染管道图1显示了HenryFord在福特汽车公司采用的装配线方法,它也是OpenGL处理数据的方法。几何数据(顶点,直线和多边形)所经历的处理阶段包括求值和基于顶点的操作,而像素数据(像素,图像和位图)的处理过程侧有所不同。在最终的像素数据写入到帧缓冲区之前,这两种类型的数据都将经过相同的最终步骤(光棚化和片断操作)。下面,详细地介绍OpenGL渲染管线的一些关键阶段:2.3.1显示列表任何数据,不管它所描述的是几何图形还是像素,都可以保存在显示列表(displaylist)中,供当前或以后使用。当然,我们也可以不把数据保存在显示列表中,而是立即对数据进行处理,这种模式也称为立即模式(immediatemode)。当一个显示列表被执行时,被保存的数据就从显示列表中取出,就像在立即模式下直接由应用程序所发送的那样。2.3.2求值器所有的几何图元最终都要通过顶点来描述。参数化曲线和表面最初可能是通过控制点以及成为基函数(Basicfunction)的多项式函数进行描述的。求职器提供了一种方法。根据控制点计算表示表面的顶点。这种方法是一种多项式映射,它可以根据控制点产生表面法线、纹理坐标、颜色以及空间坐标。2.3.3基于顶点的操作对于顶点数据,接下来的一个步骤就是"基于顶点的操作",就是把顶点变换为图元。有些类型的顶点数据(例如空间坐标)是通过一个4*4的浮点矩阵进行变换的。空间坐标从3D世界的一个位置投影到屏幕上的一个位置。如果启用了高级特性,这个阶段将更为忙碌。如果使用了纹理,这个阶段还将生成并变换纹理坐标。如果启用了光照,就需要综合变换后的顶点,表面法线,光源位置,材料属性以及其他光照信息进行光照计算,产生最终的颜色值。2.3.4图元装配图元装配的一个主要内容就是剪裁,它的任务是消除位于半空间(half-space)之外的那部分几何图元,而这个半空间是由一个平面所定义的。点剪裁就是简单地接受或拒绝顶点,直线或多边形剪裁则可能需要添加额外的顶点,具体取决于直线或多边形是如何进行剪裁的。在有些情况下,接下来需要执行一个称为透视除法(perspectivedivision)的步骤。它使远处的物体看起来比近处的物体更小一些。接下来所进行的是视口(viewport)和深度(z坐标)操作。如果启用了剔除功能(culling)并且该图元是个多边形,那么它就有可能被剔除测试所拒绝。取决于多边形模式,多边形可能被画成点的形式或者直线的形式。这个阶段所产生的结果就是完整的几何图元,也就是根据相关的颜色,深度(有时还有纹理坐标值以及和光棚化处理有关的一些指导信息)进行了变换和剪裁的顶点。2.3.5像数操作在OpenGL的渲染管线中,和单路径的几何数据相比,像素数据所经历的流程有所不同。首先,来自系统内存的一个数组中的像素进行解包,从某种格式(像素的原始格式可能有多种)解包为适当数量的数据成分。接着,这些数据被缩放、偏移,并根据一副像素图进行处理。处理结果先进行截取,然后或者写入到纹理内存,或者发送到光棚化阶段。如果像素数据时从帧缓冲区读取的,就对他们执行像素转换操作(缩放、偏移、映射和截取)。然后,这些结果被包装为一种适当的格式,并返回到系统内存的一个数组中。OpenGL有一种特殊的像素复制操作,可以把数据从帧缓冲区复制到帧缓冲区的其他位置或纹理内存中。这样,在数据写入到纹理内存或者写回到帧缓冲区之前,只需要进行一道像素转换就可以了。2.3.6纹理装配OpenGL应用程序可以在几何物体上应用纹理图像,使它们看上去更为逼真。如果需要使用多幅纹理图像,把它们放在纹理对象中是一种明智的做法。这样,就可以很方便地在他们之间进行切换。有些OpenGL实现拥有一些特殊的资源,可以加速纹理的处理。这种资源可能是专用的,高性能的纹理内存。如果确实拥有这种内存,纹理对象可能会优先进行处理,以控制这种有限和宝贵的资源的使用。2.3.7光栅化光棚化就是把几何数据和像素数据转换为片断(fragment)的过程。每个片断方块对应用于帧缓冲区中的一个像素。把顶点连接起来形成直线或者计算填充多边形的内部像素时,需要考虑直线和多边形的点画模式,直线的宽度,点的大小,着色模型以及用于支持抗锯齿处理的覆盖计算。每个片断方块都将具有各自的颜色和深度值。2.3.8片段操作在数据实际存储到帧缓冲区之前,将要执行一系列的操作。这些操作可能会修改甚至丢弃这些片断。所有这些操作都可以被启用或禁用。第一个可能执行的操作是纹理处理。在纹理内存中为每个片断生成一个纹理单元(texel,也就是纹理元素),并应用到这个片断上。接着可能进行的是雾计算,然后是剪裁测试,alpha测试,模板测试和深度缓冲区测试(深度缓冲区用于消除被隐藏的表面)。如果一个片断无法通过一个启用的测试,它的连续处理过程可能会被中断。随后,将要执行的可能是混合,抖动,逻辑操作以及根据一个位掩码的屏蔽操作。最后,经过完整处理的片断就被绘制到适当的缓冲区,最终成为一个像素并到达它的最终目的地。2.4计算机图形学计算机图形学是研究怎样用数字计算机生成、处理和显示图形的一门学科,1963年,伊凡.苏泽兰在麻省理工学院发表了名为《画板》的博士论文,标志着计算机图形学的正式诞生。此前的计算机主要是符号处理系统,自从有了计算机图形学,计算机可以部分的表现人的右脑功能了,所以计算机图形学的建立具有相当重要的意义。我国开展计算机图形设备和计算机辅助几何设计方面的研究开始于20世纪60年代中后期。进入20世纪80年代以来,我国在计算机图形学领域无论在理论研究还是在实际应用方面都取得了可喜的成果。计算机图形学是伴随着电子计算机及其外围设备而产生和发展起来的,是利用计算机研究图形的表示、生成、处理、显示的学科。经过30多年的发展,计算机图形学已成为计算机科学中,最为活跃的分支之一,并得到广泛的应用。计算机图形学的研究领域非常广泛,包括几何和自然景象模型的建立、彩色真实感图形的生成、交互技术、人机界面、图形系统标准等。他的主要应用范围包括计算机辅助设计与制造、作战指挥和军事训练、计算机动画与艺术以及地形地貌和自然资源图等。计算机图形学前沿的研究课题包括科学计算的可视化、虚拟现实技术、基于物理规律的几何造型、自然景象的模拟、计算机动画以及利用并行处理技术提高真实感图形的现实处理速度等。随着计算机系统、图形输入、图形输出设备的发展,计算机图形软件有了很大的发展。在这基础上,计算机图形学所设计的算法通过了几十年热烈的讨论和探索,也越来越丰富和完善。计算机图形学设计的算法非常丰富,大致可分为以下几类:(1)基本图元素的生成算法,如生成直线、圆弧、二次曲线、区域填色、反走样等。(2)基本图元素的几何变换、投影变换、裁剪等。(3)图元素(点、线、环、面、体)的求交与分类以及集合运算。(4)自由曲线和曲面的生成、插值、拼接、分解等。(5)隐藏面和隐藏线的消除以及具有光照颜色效果的真是图形显示。(6)不同字体的点阵表示,矢量中、西文字符的生成及变换。(7)模糊景物的生成。(8)三维或高维数据场的可视化。(9)三维形体的实时显示和图形的并行处理。(10)虚拟现实环境的生成及其控制算法等。围绕着写算法,多年来发表了很多论文,有些算法越来越完善,甚至实现了固化。然而有些算法还不是十分理想,可以进行适当的修改来进一步提高其效率。2.3MFC框架一.MFC概述MFC是一个编程框架MFC(MicrosoftFoundationClassLibrary)中的各种类结合起来构成了一个应用程序框架,它的目的就是让程序员在此基础上来建立Windows下的应用程序,这是一种相对SDK来说更为简单的方法。因为总体上,MFC框架定义了应用程序的轮廓,并提供了用户接口的标准实现方法,程序员所要做的就是通过预定义的接口把具体应用程序特有的东西填入这个轮廓。MicrosoftVisualC++提供了相应的工具来完成这个工作:AppWizard可以用来生成初步的框架文件(代码和资源等);资源编辑器用于帮助直观地设计用户接口;ClassWizard用来协助添加代码到框架文件;最后,编译,则通过类库实现了应用程序特定的逻辑。封装构成MFC框架的是MFC类库。MFC类库是C++类库。这些类或者封装了Win32应用程序编程接口,或者封装了应用程序的概念,或者封装了OLE特性,或者封装了ODBC和DAO数据访问的功能,等等,分述如下。对Win32应用程序编程接口的封装用一个C++Object来包装一个WindowsObject。例如:classCWnd是一个C++windowobject,它把Windowswindow(HWND)和Windowswindow有关的API函数封装在C++windowobject的成员函数内,后者的成员变量m_hWnd就是前者的窗口句柄。对应用程序概念的封装使用SDK编写Windows应用程序时,总要定义窗口过程,登记WindowsClass,创建窗口,等等。MFC把许多类似的处理封装起来,替程序员完成这些工作。另外,MFC提出了以文档-视图为中心的编程模式,MFC类库封装了对它的支持。文档是用户操作的数据对象,视图是数据操作的窗口,用户通过它处理、查看数据。对COM/OLE特性的封装OLE建立在COM模型之上,由于支持OLE的应用程序必须实现一系列的接口(Interface),因而相当繁琐。MFC的OLE类封装了OLEAPI大量的复杂工作,这些类提供了实现OLE的更高级接口。对ODBC功能的封装以少量的能提供与ODBC之间更高级接口的C++类,封装了ODBCAPI的大量的复杂的工作,提供了一种数据库编程模式。②从CWinApp、CDocument、CView、CMDIFrameWnd、CMDIChildWnd类对应地派生出CTApp、CTDoc、CTView、CMainFrame、CChildFrame五个类,这五个类的实例分别是应用程序对象、文档对象、视对象、主框架窗口对象和文档边框窗口对象。主框架窗口包含了视窗口、工具条和状态栏。对这些类或者对象解释如下。(1)应用程序应用程序类派生于CWinApp。基于框架的应用程序必须有且只有一个应用程序对象,它负责应用程序的初始化、运行和结束。(2)边框窗口如果是SDI应用程序,从CFrameWnd类派生边框窗口类,边框窗口的客户子窗口(MDIClient)直接包含视窗口;如果是MDI应用程序,从CMDIFrameWnd类派生边框窗口类,边框窗口的客户子窗口(MDIClient)直接包含文档边框窗口。如果要支持工具条、状态栏,则派生的边框窗口类还要添加CToolBar和CStatusBar类型的成员变量,以及在一个OnCreate消息处理函数中初始化这两个控制窗口。边框窗口用来管理文档边框窗口、视窗口、工具条、菜单、加速键等,协调半模式状态(如上下文的帮助(SHIFT+F1模式)和打印预览)。(3)文档边框窗口文档边框窗口类从CMDIChildWnd类派生,MDI应用程序使用文档边框窗口来包含视窗口。(4)文档文档类从CDocument类派生,用来管理数据,数据的变化、存取都是通过文档实现的。视窗口通过文档对象来访问和更新数据。(5)视视类从CView或它的派生类派生。视和文档联系在一起,在文档和用户之间起中介作用,即视在屏幕上显示文档的内容,并把用户输入转换成对文档的操作。(6)文档模板文档模板类一般不需要派生。MDI应用程序使用多文档模板类CMultiDocTemplate;SDI应用程序使用单文档模板类CSingleDocTemplate。应用程序通过文档模板类对象来管理上述对象(应用程序对象、文档对象、主边框窗口对象、文档边框窗口对象、视对象)的创建。2.4基于OpenGL+MFC的三维模拟的编程环境配置1.创建MFC项目①创建项目文件。选择File|New菜单项,新建一个基于对话框的项目文件MyDlgOpenGL;②修改对话框模板。删除对话框中的静态文本,调整控件的位置;2.配置基于OpenGL+MFC的开发环境①将glu.dll,glu32.dll,glut.dll,glut32.dll,opengl32.dll文件拷贝到操作系统WINNT/System32目录下。②将gl.h,glaux.h,glu.h,glut.h拷贝到MicrosoftVisualStudio/VC98/Include/GL目录中中。③将glaux.lib,glu32.lib,glut32.lib,opengl32.lib拷贝到MicrosoftVisualStudio/VC98/Lib目录中。④添加OpenGL开发库文件到项目在编译程序的时候选择Project|Setting菜单,在Link标签中的Object/librarymodules编辑框中输入“opengl32.lib,glut32.lib,glu32.lib,glaux.lib”。⑤创建新类,添加消息映射。选择View|ClassWizard菜单项,打开MFC对话框,在AddClass之中选择New,以便添加一个新类COpenGL,且该类的基类选择genericCWnd;最后利用MFCClassWizard为COpenGL类添加消息WM_CREATE,WM_PAINT的映射。3.初始化OpenGL①设置像素格式:为CMyTestView类添加成员函数BOOLbSetupPixelFormat(void),用于与OpenGL相关的设置/*定义像素存储格式*/PIXELFORMATDESCRIPTORpfd={sizeof(PIXELFORMATDESCRIPTOR),//pfd结构的大小1,//版本号PFD_DRAW_TO_WINDOW|//支持在窗口中绘图PFD_SUPPORT_OPENGL|//支持OpenGLPFD_TYPE_RGBA,//RGBA颜色模式24,//24位颜色深度0,0,0,0,0,0,//忽略颜色位0,//没有非透明度缓存0,//忽略移位位0,//无累加缓存0,0,0,0,//忽略累加位32,//32位深度缓存0,//无模板缓存0,//无辅助缓存PFD_MAIN_PLANE,//主层0,//保留0,0,0//忽略层,可见性和损毁掩模};intpixelformat;if((pixelformat=ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd))==0){MessageBox("ChoosePixelFormatfailed");returnFALSE;}if(SetPixelFormat(m_pDC->GetSafeHdc(),pixelformat,&pfd)==FALSE){MessageBox("SetPixelFormatfailed");returnFALSE;}returnTRUE;②初始化创建OpenGLRC:hrc=wglCreateContext(m_pDC->GetSafeHdc());wglMakeCurrent(m_pDC->GetSafeHdc(),hrc);并添加WM_CREATE消息处理函数,然后在OnCreate函数中进行调用://TODO:AddyourspecializedcreationcodehereInit();③初始化的获取dc:m_pDC=newCClientDC(this);ASSERT(m_pDC!=NULL);④设置OpenGL视锥体即投影变换矩阵glMatrixMode(GL_PROJECTION);//在修改前重设坐标系glLoadIdentity();⑤设置视口变换://Settheviewport视口tobetheentirewindowglViewport(0,0,w,h);gluPerspective(45,ratio,1,1000);⑥设置OpenGL模型变换glMatrixMode(GL_MODELVIEW);glLoadIdentity();4.实现应用程序逻辑在本雨雪粒子系统中为CMyTestView类添加了许多成员函数:InvertWaveMap()函数来编程下雨效果;DrawWave()函数用来编程雨粒子下落时的水波属性;LnitializeOpenGL()行数用来编程初始化openGL场景;OnSize()函数用来添加窗口缩放时的图形变换函数;OnTime()用来添加定时器响应函数和场景更新函数;Lnit()函数用来编程雪粒子属性。5.清理工作:(析构函数中释放dc,rc指针)voidCMyRainView::OnDestroy(){CView::OnDestroy();//TODO:Addyourmessagehandlercodehere}

第三章水波的计算机模拟原理和关键技术3.1水的流体物理性质水波很容易被认为是一种横波,实际上并非如此。在平的情况下,水的表面是水平的。水面发生扰动时,使水面恢复水平的回复力有两个,一个是重力,另一个是表面张力。水波中,对水面质点提供的回复力在波长很小时,表面张力的作用是主要的,这种波叫做表面张力波。对于波长很长很长的波,表面张力的作用可以忽略,波动主要是重力作用的结果,这种波叫做重力波。由于水的不可压缩性,波峰中的水必然是从附近的波谷中流出来的。因此,水波中的每个质点的运动都是由纵向运动和横向运动合成的。3.1.1难以压缩性不同流体受温度和压力变化影响,其密度会有不同的改变,而水这种流体的变化则不明显,水的压缩性与澎涨性与空气对比则很小。如在26℃和一个大气压的条件下,水的密度为996千克/米3,而空气仅约1.18千克/米3纳维-斯托克斯方程:牛顿第二定律在不可压缩粘性流动中的表达式。简称N-S方程。此方程是法国力学家、工程师C.-L.-M.-H.纳维于1821年创立,经英国物理学家G.G.斯托克斯于1845年改进而确定的。它的矢量形式为:(3-1)在直角坐标中的分量形式为:(3-2)(3-3)(3-4)(3-5)(3-6)(3-7)式中ρ、ν、p、u、f分别为液体密度、运动粘性系数、动水压强、流速矢量、单位质量的质量力;墷为矢量微分算符;为拉普拉斯算符。为指定点处由于时间改变而引起的速度变化率,称为当地加速度;(u·墷)u为指定瞬时由于空间位置改变而引起的速度变化率,称为迁移加速度;与ν墷2u分别为作用于单位质量液体表面的合压力与合粘性力;(ux,uy,uz)及(fx,fy,fz)为u及f在直角坐标中的投影。在某些情况下,合粘性力很小,可忽略不计,于是N-S方程简化为理想液体的欧拉方程。即:(3-8)对于需作流场分析的水力学问题,N-S方程有特别重要的意义。它和三维连续性方程一道组成不可压缩粘性流动完整方程组,附加一定的初始条件和边界条件,从理论上讲,就可以解出流速分布和压强分布。但N-S方程是非线性的二阶偏微分方程,仅在一些特定条件下,才能求出解析解。对于低雷诺数流动,可全部地或部分地略去惯性项,求得蠕动流近似解。对高雷诺数流动,在物体表面附近的边界层内,必须考虑粘性影响,按边界层方程求解;边界层外,粘性效应可以忽略,用欧拉方程近似求解。在很多情况下,特别是中等雷诺数的流动,可求出N-S方程的数值解。大型电子计算机的应用,为N-S方程的数值解开辟了广阔的前景。3.1.2粘滞性流体均有不可忽视的粘滞力,它产生于分子间相互吸引作用,在流体力学中称为“内聚力”。粘滞性随温度升高而降低,水在26℃时为空气的48倍(水=0.89×10-3牛顿·秒/米,空气=1.83×10-3牛顿·秒/米),而在20℃时约为59倍。水在静止时各方向压力平衡,粘滞性不显示作用,当受到外力大于水的内聚力时,水层压力产生变化,原分子间的连结被冲散,由于相互吸引关系产生水层摩擦来对抗外力,直至外力被削弱,这个现象即是水的阻力过程。外力越大,内聚力被冲散越严重,分子间摩擦现象越激烈,此即物休在水中运动时构成阻力的根源。游泳时一切动作都将取决于水粘滞性形成的阻力作用,是运动环境力的重要因素。3.1.3流动性由于水在流体中粘滞力是较小的,故抗拉、抗压力较弱,受剪切力和水层压力影响时,若该力大于原有内聚力,水即从高压区流向低压区,或按外力方向流动。水对外力的抗力与外力的速度成正比,如手划水时速度越慢,被推向前方的水越多。速度越快时会引起压力重新分配,被推动向前的水量反而越少。而大部被推动水流会绕过手掌挡水面流向手的后面低压区。划动如能持续加速即可始终保持挡水面的正压力,起到划静水(相对静止)的作用。游泳时一切制造推动力的动作,都应是加速的才能不使水的流动特性把动力转移,从而获得推动力。描述流体运动的两种方法之一:拉格朗日法是以研究单个流体质点运动过程作为基础,综合所有质点的运动,构成整个流体的运动。以某一起始时刻每个质点的坐标位置(a、b、c),作为该质点的标志。任何时刻任意质点在空间的位置(x、y、z)都可以看成是(a、b、c)和t的函数拉格朗日法基本特点:追踪流体质点的运动优点:可直接运用固体力学中质点动力学进行分析微积分中的拉格朗日定理(拉格朗日中值定理)设函数f(x)满足条件:(1)在闭区间[a,b]上连续;(2)在开区间(a,b)可导;则至少存在一点ε∈(a,b),使得f(b)-f(a)b-af(b)=f(a)+f(ε)'(b-a)[证明:把定理里面的c换成x在不定积分得原函数f(x)={[f(b)-f(a)]/(b-a)}x.做辅助函数G(x)=f(x)-{f(b)-f(a)]/(b-a)}x易证明此函数在该区间满足条件:1,G(a)=G(b);2.G(x)在[a,b]连续;3.G(x)在(a,b)可导.此即罗尔定理条件,由罗尔定理条件即证]3.2基本原理3.2.1建立区域采样法水波数学模型区域采样时计算机图形学中常用的方法,仅仅一片小区域的影响可以在保证效率的前提下得到较好的效果。水波区域采样法原理:吧睡眠堪称一个二维的坐标系,点(x,y)坐标值将受到其周围区域的坐标影响,最简单的情况是假设仅仅被(x-1,y-x).(x-1,y).(x-1,y+1).(x,y+1).(x+1,y).(x+1,y-1).(x+1,y+1)和(x,y-1)影响,基于这个假设推到计算水波振幅的公式。记F(x,y)为(x,y)坐标的水波振幅且有正负之分,(x,y)坐标水波下一时刻的振幅F~(x,y)将由当前时刻的F(x,y).f(x-1,y-1).F(x-1,y).f(x-1,y+1).f(x,y+1).f(x+1,y).f(x+1,y-1)f(x+1,y-1)决定,假设F(x-1,y-1).f(x-1,y).f(x-1,y+1)f(x,y+1)f(x+1,y)f(x+1,y-1)f(x+1,y-1)和f(x,y-1)对f~(x,y)的影响相同则:F~(x,y)=a{f(x-1,y-1)+f(x-1,y)+f(x-1,y+1)+f(x,y+1)+f(x+1,y)+f(x+1,y-1)+f(x+1,y+1)+f(x,y-1)}/4-f(x,y)次公式与以往水波公式相比,计算量大大减少,编程时,用一个for循环就可以实现。3.2.2水波扩散分析及解决方法每次鼠标点击到水面上,都会引起水波上升,或者下降,水波的能量都会被分配到一个增大的区域,这就意味着水波的振幅将会逐渐递减,编程时使用一个阻呢系数模拟这种变化,这个系数是一个振幅的百分比参数,他使高振幅的水波迅速衰减,而使低振幅的水波缓慢衰减,根据分析,取阻呢系数为0.002合适。在忽略鼠标不断点击水波使水波能量增加的影响(改影响在水波显示技术中考虑)下,假设水波前后时刻总能量相等,编程时,不断地变化,交换两个缓冲区中的数据,结合上面的公式,便可得到水波的编程原理。

第四章基于OpenGL的水波模拟4.1系统设计模拟水表面动画的方法大量的文献对海洋表面仿真与动画,无论是在计算机图形学和海洋学等领域都有讨论。而且也已经有很多种方法对其进行仿真。1比如用sin函数来进行仿真,也就是运用了水波的特性;2用傅立叶和里维斯变换描写水波在计算机图形学里的实现,这种方法伸缩性很好,不仅可用于以高品质的水动画录像资料而且也可以用于实时性的仿真;3当然也用运用物理模型的方法,这种方法运用了一些理想状态,然后用图形学的方法把它表示出来,典型的就是运用著名的流体方程Navier-Stokes方程,这个复杂的数学程序的有益之处是转换高程和速度势成为一个比较简单动力学;4就是运用粒子系统,这种方法的思路是将流体看作粒子集;以上四种方法是前人用的最多的,对于第一种,这种方法比较简单而且也给出了实际的数学模型,该模型对于硬件要求比较低,模拟出来的结果也可以达到一般的要求;第二种方法可以模拟出很好的海面效果,但是这种方法对硬件的配置要求比较高,尤其是GPU;第三种方法运用了著名的流体方程,但是转化的情况其实是只是简单的海洋高度场,包括上升时候的色散关系;第四种方法可以模拟浪花飞溅但是不能模拟水波。本文所采用的方法是第一种方法,也就是sin函数,因为sin函数的数学模型比较简单,连续性和可微性比较好,但是sin函数非常光滑,而海水表面并不是光滑的,尤其是在浪尖和浪底的时候出现尖锐处,我们应用一些方法解决了这个问题,使得效果更佳。4.2水波模拟的算法设计要对某种自然现象进行模拟仿真,就必须对该现象的特性有很好的认识。比如对于本文所仿真的对象--水波,就要对水波的诸多特性如扩散性、衰减性、反射性以及水的折射等都要有所认识,并最终通过程序算法体现在程序中。这些关于波的特性属于普通物理的研究范畴,因为在模拟时需要的是实时的渲染,而每秒种至少要渲染15帧以上才能使水波得以平滑的显示。考虑到普通微型计算机的运算速度,不能用乘、除法,更不可以使用正、余弦函数以精确的公式来构造水波,我们只能通过使用简单而高速的加、减法的近似算法来实现。可以用两个与水池图象一样大小的数组buf1和buf2来保存水面上每一个点(离散化的点,对应于每一个像素)的前、后两时刻的波幅数据。在无外力干扰时的稳定状态下水面是一个平面,水面各点的波幅都为0。当有外力干扰,如向水池投一颗石子会使水面泛起层层的涟漪。我们不能被现象所误导,实际上并非水面上的点在向外扩散,而是仍停在原地上下移动,由于振动幅度的变化而引起视觉上的错觉。而且水波上的任何一点在任何时候都是通过振幅的变化把能量以自己为圆心向四周扩散,我们可以近似认为一个点只会对相临的前、后、左、右四个点有影响。这样我们就可以用归纳法来根据任一点在某时刻周围四点的振幅来求出该点在下一时刻的震动幅度。假设表示该影响关系的公式为:A0’=a×(A1+A2+A3+A4)+b×A0(4-1)其中a、b为待定系数,A0’为0点下一时刻的振幅,A0、A1、A2、A3、A4均为为当前时刻的周围各点振幅。在不考虑衰减的情况下波的能量守恒,即各点振幅之和守恒(能量通过振幅来体现),可以用(4-2)表示:A0’+A1’+...+An’=A0+A1+...+An(4-2)将(4-1)代入(4-2):(4a+b)×A0+(4a+b)×A1+...(4a+b)×An=A0+A1+...+An化简可得4a+b=1,取a=1/2、b=-1可以满足条件。而且除2可以用运算速度很快的移位运算符">>"来进行。公式一代入系数可得到无阻尼状态下的周围四点对中心点的影响关系式:A0’=(A1+A2+A3+A4)/2-A0推广到水面任一点:下一时刻任意一点的波幅等于与该点紧邻的前、后、左、右四点的波幅之和的一半与该点在上一时刻的波幅之差。但水在实际中是存在阻尼的,水波会在扩散过程中逐渐衰减直至消失。所以还要对波幅数据进行衰减处理,让每一个点在经过一次运算后,波幅按一定的比例衰减,衰减率经笔者的实验,取1/32比较合适,同时它也可以通过移位运算很快的获得。到此为止,已将水波的扩散和衰减等特型用数学模型表示了出来,下面是具体计算波幅数据的主要代码:voidSpread(){……for(inti=BACKWIDTH;i{//能量的扩散buf2[i]=((buf1[i-1]+buf1[i+1]+buf1[i-BACKWIDTH]+buf1[i+BACKWIDTH])>>1)-buf2[i];//能量的衰减buf2[i]-=buf2[i]>>5;}//交换前后两时刻的能量缓冲区short*ptmp=buf1;buf1=buf2;buf2=ptmp;……}虽然模拟了对波的传播过程,但如不考虑水面起伏的水波引起的对光的折射也是不逼真的,也正是由于水面上部的光线反射,才使我们感觉到水波的起伏。根据光学有关知识,我们所看到的水下的景物并非在观察点的正下方,而是存在一定的偏移。偏移的程度同水波的斜率,水的折射率和水的深度都有关系,出于对处理速度的考虑同样也不能对其进行精确的模拟。只能做线性的近似处理。因为水面越倾斜,所看到的水下景物偏移量就越大,所以,我们可以近似的用水面上某点的前后、左右两点的波幅之差来代表所看到水底景物的偏移量:voidRender(){……intxoff,yoff;intk=BACKWIDTH;for(inti=1;i{for(intj=0;j{//计算偏移量xoff=buf1[k-1]-buf1[k+1];yoff=buf1[k-BACKWIDTH]-buf1[k+BACKWIDTH];//判断坐标是否在窗口范围内if((i+yoff)<0){k++;continue;}if((i+yoff)>BACKHEIGHT){k++;continue;}if((j+xoff)<0){k++;continue;}if((j+xoff)>BACKWIDTH){k++;continue;}//计算出偏移象素和原始象素的内存地址偏移量intpos1,pos2;pos1=ddsd1.lPitch*(i+yoff)+depth*(j+xoff);pos2=ddsd2.lPitch*i+depth*j;//复制象素for(intd=0;dBitmap2[pos2++]=Bitmap1[pos1++];k++;}}}在无外力影响的情况下,是不会自发产生水波的,必须对水面施加某种激励才能引起波源的扩散。而且扩散的速度与范围也是同激励的能量大小与受力范围有关的,我们可以通过在程序中人为的修改振幅缓冲区buf,来模拟外界的激励比如雨点入水等。可以在雨点落水的地点来一个负的"尖脉冲",即让buf[x,y]=-n。经过多次实验,n的范围取值在(32~128)之间比较合适。受力半径的控制也好办,只须以入水中心点为圆心,画一个以雨点半径为半径的圆,让这个圆里所有的点都来这么一个负的"尖脉冲"就可以了,显然这里也是做的近似处理:voidDropStone(intx,/*x坐标*/inty,/*y坐标*/intstonesize,/*半径*/intstoneweight/*能量*/){……//判断坐标是否在屏幕范围内if((x+stonesize)>BACKWIDTH||(y+stonesize)>BACKHEIGHT||(x-stonesize)<0||(y-stonesize)<0)

return;……for(intposx=x-stonesize;posxfor(intposy=y-stonesize;posyif((posx-x)*(posx-x)+(posy-y)*(posy-y)<stonesize*stonesize)buf1[BACKWIDTH*posy+posx]=-stoneweight;……}虽然在前面的推导中多处采用了看似过分的非常近似的处理,但是完全不必担心,事实证明,用这种方法,在速度和图象上都可以获得非常好的效果。下边就是从其中截取的一帧画面,很逼真的再现了水波的产生过程。这种用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论