地形纹理混合.doc_第1页
地形纹理混合.doc_第2页
地形纹理混合.doc_第3页
地形纹理混合.doc_第4页
地形纹理混合.doc_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

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

文档简介

D3DTOP_DISABLE:禁用纹理层颜色输出.D3DTOP_SELECTARG1:将该纹理层的第一个混合参数直接输出.对于D3DTSS_COLOROP,则输出由D3DTSS_COLORARG1指定的第一个表示RGB的参数;对于D3DTSS_ALPHAOP,则输出由D3DTSS_ALPHAARG1指定的第一个表示ALPHA的参数.D3DTOP_SELECTARG2:同上.D3DTOP_MODULATE:将两个混合参数相乘后输出.D3DTOP_MODULATE2X:将两个混合参数相乘后再乘以2输出.D3DTOP_MODULATE4X:将两上混合参数相乘后再乘以4输出.D3DTOP_ADD:将两上混合参数相加后输出.D3DTOP_ADDSIGNED:将两个混合参数相加后减去0.5输出.(可以这样理解:本来范围在0,1里,减0.5使其范围限制在-0.5, 0.5中.这样相加后,比较暗的部分,即负数部分,将对原来的纹理产生衰减,而较亮部分则对原来的纹理增强.可用作细节纹理.如果有的显卡不支持D3DTOP_ADDSIGNED方式,可考虑采用D3DTOP_MODULATE2X来模拟这种效果).D3DTOP_ADDSIGNED2X:同上,结果再乘以2输出.D3DTOP_SUBTRACT:将两个混合参数相减后输出.D3DTOP_ADDSMOOTH:将两个混合参数的和减去两个混合参数的积.D3DTSS_COLORARG1 与 D3DTSS_COLORARG2 可以指定的纹理混合参数:D3DTA_CURRENT:前一个纹理层的输出颜色.如果在第0层,则为漫反射颜色.D3DTA_DIFFUSE:像素的漫反射颜色值.这种颜色是在使用GOURAUD着色模式时对顶点的漫反射颜色插值得到的.D3DTA_TEXTURE:当前纹理的颜色值.D3DTA_TFACTOR:参数值为SetRenderState()通过D3DRS_TEXTURE_EFACTOR设置的系数值.D3DTA_SPECULAR:参数值为像素的镜面反射颜色值.这种颜色是在使用高洛德着色模色时对顶点的镜面反射颜色插值得到的.D3DTA_SELECTMASK:该状态在设置纹理参数时不起作用.D3DTA_TEMP:参数值存储在一个临时寄存器中.D3DTA_CONSTANT:参数值为一个常数值.D3DTA_COMPLEMENT:该参数必须与以上任意一个参数同时设置(或操作?),表示用一减去原参数.D3DTA_ALPHAREPLICATE:该参数必须与以上除了D3DTA_COMPLEMENT之外的任一参数同时设置,表示将原参数的ALPHA值复制到R,G,B中. 本文来自CSDN博客,转载请标明出处:/flipcode/archive/2008/03/11/2168567.aspx我重新观察了一下Torque引擎Demo的地形,发现在他在一个方块内最多用了3张贴图。这3张贴图就需要3个TextureStage,再加上2个提供Alpha值的Stage,总共就是5个TextureStage。这对显卡要求太高,至少我的显卡只支持4个TextureStage。那么就必须使用MultiPass了,多遍渲染。这篇文章说的把Alpha信息存储在顶点Diffuse里面的方法,还是值得考虑的。因为如果是用Alpha图的话,Alpha图总会被拉伸得很厉害,使得地形上不同贴图之间仍然不能自然过渡。除非你的地形有更大的区域概念,对一个区域使用一张Alpha图,这可能会解决Alpha图被过度拉伸的问题。不然,你只使用全局唯一的一张Alpha图的话,将很难收到理想的效果。 由定点的Diffuse提供Alpha有一个好处,那就是D3D会做插值运算,这样就不会让某一点的Alpha扩展成斑块,因为它扩展出来的新值会被D3D插值运算的。那么要实现Torque那样的最多支持3张纹理混合,同一个地形就需要2份Diffuse。可以考虑使用多流的技术,让Diffuse数据作为一个单独的流。 原文 地形多层纹理混合加阴影渲染方法地形由于十分庞大,需要大量顶点,所以往往占用很多内存空间,那么就应该在地形贴图上想办法节约空间。很多游戏的地形,虽然看上去不同地点的纹理好像互不相同,地表纹理十分丰富,但其实真正用的贴图是很少的,之所以还能产生地表纹理变化多端的视觉效果,是因为使用了Alpha混合和阴影,从而产生一种错觉。2.5D的网络游戏奇迹(MU)、全3D引擎Torque(多人联网FPS游戏部落2即使用此引擎)、全3D的滑雪游戏极限滑雪(SupremeSnowboarding),都是这么做的。(参见文章末尾的截图) 我对此设想了一个解决方案。需要用到顶点的Diffuse颜色、3个TextureStage。其实所谓的多层纹理,具体到一个三角形上的时候,很多游戏只用了2层纹理来做Alpha混合(因为也许玩家的显卡只支持2层MultiTexture混合),然后再一层光照纹理。前2层纹理要做Alpha混合,Alpha来自哪里?若使用Alpha贴图,就必然再增加一层TextureStage,而我选择使用顶点的Diffuse就可以省掉这一层TextureStage:由Diffuse的Alpha通道提供Alpha值供前两层TextureStage混合使用。下面是在D3D中的设置: /TextureStage0 pd3dDevice-SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1); pd3dDevice-SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE); pd3dDevice-SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_DISABLE); /TextureStage1 pd3dDevice-SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_BLENDDIFFUSEALPHA); pd3dDevice-SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE); pd3dDevice-SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT); pd3dDevice-SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE); 在TextureStage0,什么也没做,把第一层纹理原封不动的留给TextureStage1;在TextureStage1,COLOROP使用D3DTOP_BLENDDIFFUSEALPHA,也就是使用来自顶点Diffuse的Alpha值作为混合因子混合第2层纹理和TextureStage0原封不动留下来的第1层纹理。混合公式如下(来自DX帮助文档): Result=Arg1*Alpha+Arg2*(1Alpha) Arg1是来自第2层纹理的颜色,Arg2是来自TextureStage0原封不动留下来的第1层纹理的颜色。并且,这里的Alpha值是D3D插值运算后得到的,因此混合效果很平滑。 你不相信2层纹理混合就能得到丰富的地表视觉效果吗?你应该相信,因为虽然Arg1和Arg2总是恒定不变的来自2个贴图,因此对三角形上的同一点来说,这两个是常量,但Alpha值却是个变量,Alpha值取不同的值就会产生不同的Result。 假设与Arg1相对应的贴图是一个草地的贴图,与Arg2相对应的贴图是一个沙地的贴图,在一片地形区域内,仅使用这两张贴图,但是由于各顶点的Diffuse的Alpha值不同,你会看到最终渲染出来的这片地形区域,草地的分布并不均匀,有些地方草的样子多一些,有些地方沙的样子多一些。这种效果看上去已经很自然了。 当然并不限制你在一个地形场景上使用更多的地表纹理,但是对一个三角形来说,2张纹理已经足够,其它纹理请用在其它三角形上吧,这可以产生更丰富的地貌。比如你想让另一片地形区域是雪地和岩石的风格,那么在那片区域上就使用1张雪地贴图、1张岩石贴图。现在这个关卡里面共有4张贴图了,但同一个三角形仍然只使用2张贴图(这是硬件的限制啊!)。 现在来说阴影。前面已经使用了顶点Diffuse的Alpha通道,现在他的RGB三个分量也要派上用场了。在D3D中设置如下: /TextureStage2 pd3dDevice-SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_MODULATE); pd3dDevice-SetTextureStageState(2,D3DTSS_COLORARG1,D3DTA_DIFFUSE); pd3dDevice-SetTextureStageState(2,D3DTSS_COLORARG2,D3DTA_CURRENT); pd3dDevice-SetTextureStageState(2,D3DTSS_ALPHAOP,D3DTOP_DISABLE); 这是第3个TextureStage,COLOROP为相乘,Arg1设为Diffuse,是来自经过D3D插值运算的顶点Diffuse颜色,Arg2是Current就是TextureStage1产生的结果。混合公式如下: Result=Arg1*Arg2 颜色虽是RGB三个字节(或者其它颜色格式),但D3D会将它们拆成单独的3个RGB通道值(0-1之间的浮点数)。相乘运算可以贴上彩色的光影效果。 有一个问题是,人们当初选择使用光照图就是为了能够提高光影的精确度,因为顶点光照只作用于顶点,虽然渲染API会在顶点之间做插值,但这也只在顶点很密集的时候才会有很精确的光照,如果定点很稀疏甚至不能产生正确的光照效果。这里使用顶点Diffuse,会不会也得不到令人满意的光照效果呢? 我想过使用一整张光照图铺在整个地形上,但我忽然想起这与基于heightmap的地形生成技术面临一个同样的问题,精度。使用heightmap,为了减小游戏体积,这个heightmap不可能很大,不可能每一个高度点只对应一个顶点,而是多个顶点被映射到同一个高度点上去了。一整张光照图也面临同样的问题,也许多个顶点使用光照图上的同一个像素呢?如果两个顶点用的是光照图上的同一个像素,那顶点之间的空间也肯定是用这个像素点了,这样是不会提高精度的。把光照图的尺寸增大?那是选择512*512呢,还是1024*1024? 而实际上,LOD地形的顶点总是很密集的。至少在靠近照相机的区域是这样的,往往比室内建筑的顶点还要密集。虽然还没密集到可以让D3D的聚光灯产生满意效果的地步,但已足够使用顶点光照模拟地形因高低起伏而产生的阴影效果。何况业界普遍认为地形渲染的精度是低于室内渲染一个档次的(新游戏FarCry是个例外)。 更妙的是,顶点光照信息可以存储在高度图里,我们把高度点从一个unsignedchar改为一个多字节的数据结构: structHeightPoint unsignedcharheight;/用于计算定点的Y坐标值,用于渲染地形高度起伏 unsignedcharalpha;/定点diffuse的alpha,用于多层纹理混合 unsignedcharred;/顶点diffuse的red,用于光照 unsignedchargreen;/顶点diffuse的green,用于光照 unsignedcharblue;/顶点diffuse的blue,用于光照 ; 这样高度图信息不仅包含高度信息,也包含多层纹理混合信息、光照信息。当动态创建地形的时候,在读取高度数据的同时也能得到与该顶点对应的diffuse值,非常方便。 下面是用DX自带的MFCTex程序验证理论。3个TextureStage正是使用上面所说的设置方法。 图1 env2.bmp是一个砖墙的贴图,caust11.tga是一个水面波纹的贴图,env3.bmp没有被使用。Diffuse颜色是0x77ff0000,是纯红色,但alpha值为119。 Stage0把env2.bmp的图像数据原封不动的保留给Stage1。Stage1的COLOROP使用D3DTOP_BLENDDIFFUSEALPHA的方法,以diffuse的alpha值(119=0.53)为混合因子混合caust11.tga和env2.bmp,公式是:ResultOfStage1=caust11.tga*0.53+env2.bmp*(10.53),得到的视觉结果是我们既能看到砖墙又能看到水面波纹,他们被半透明的混合起来了。Stage2使用相乘,把diffuse的RGB三分量与ResultOfStage1(Current就是ResultOfStage1)上对应点的RGB三分量乘起来,由于diffuse的RGB是ff0000纯红色,完全没有green和blue分量,所以这次得到的视觉结果是整个墙壁偏红色。这样我们就产生了墙壁上被投上了水面折射的波纹,而整个墙壁又被一片红光照亮的效果。 下面来看看Torque引擎、极限滑雪的地形贴图渲染效果。 首先是Torque。Torque引擎的Demo所使用的纹理文件都没有打包,所以我很容易找到这些文理,用Photoshop给它们画上标记,再到游戏中看他们是如何被混合、以及怎样贴到地面上去。这个Demo只用了3张地形纹理:1个grass.jpg,1个sand.jpg,1个patchy.jpg。每张纹理我先用红色粗线条勾出它的4条边,再在左上角和右下角用写上它的文件名,我还给它们写上中文译名,grass.jpg是“草”,sand.jpg是“沙”,patchy.jpg是“稀疏的草地”。来看截图: 图2 每张地形纹理都是256*256的,从空中这个角度看,每张纹理都被映射到地形上一个相当大的方形区域,所以镜头贴近地面的时候,会变得很模糊,但Torque会在这时贴上细节纹理(参见后面的截图),一个叫detail1.png的图片文件(还是只有1张,但效果很好),这是另一个技术了,在此不表。图中,凡是黄色区域都来自sand.jpg。我们看那个左边有“稀疏的草地”的方形区域,这个区域用的是patchy.jpg和sand.jpg两张纹理混合的,“地”字就刚好位于混合边界,所以模糊了。混合因子不是顶点diffuse的alpha吗?所以这个区域里面,要有更多的顶点,没问题,Torque使用四叉树来创建地形,这个方形区域里面被细分为更小的方形区域,而且不是平衡的(LOD技术),所以有足够的顶点,同时看上去混合边界是扭曲的。这个Demo可以切换为线框渲染模式,我好好观察了那些顶点的分布,确实跟Alpha混合的分布相一致。 再来一张截图: 图3 从这个截图里面看出,阴影的存在确实起到了丰富视觉效果的作用。看左边那个方形区域,几乎全是沙地,但有阴影的存在,效果就好多了。你可能觉得它的阴影很细致,但别忘了这是一个全3D的FPS游戏,我是在很高的空中俯拍的。 另一个游戏极限滑雪,这是欧洲某个国家制作的商业游戏。虽是商业游戏,它的纹理文件也没有打包,赤裸裸的jpg、tga,所以我把这些纹理都替换为只有一个颜色的图片,再勾勒出图片的四条边,打上文件名。由于是个滑雪游戏,所以场景中最常见的颜色就是白色了,所以大范围内只使用同一张纹理用得理直气壮。 图4 当然要加上阴影,不然真的会灼伤玩家的眼睛呢。有了阴影,效果好一些了。再加上彩色的光影,还蛮令人着迷的,看图: 图5 游戏中的山头和公路都需要别的纹理来混合。 图6 看图6的阴影,尤其是左边的,有较为明显的梯级,右边的呈矩形,应该是那棵树的影子,但却很涣散,很不对劲,跟顶点光照的效果十分相像,可能是场景编辑器把计算出来的影子信息存储到顶点的diffuse中去了。 这个游戏的雪地纹理只有2张,另一张出现的频率较小。 附:Torque的细节纹理 3D地形多层纹理混合加阴影渲染方法(2)作者: 来源: 发布时间:07-05-14 浏览: 次 公益IQ题:见过有工作效率比google更低的公司吗?答案是:没有!而实际上,LOD地形的顶点总是很密集的。至少在靠近照相机的区域是这样的,往往比室内建筑的顶点还要密集。虽然还没密集到可以让D3D的聚光灯产生满意效果的地步,但已足够使用顶点光照模拟地形因高低起伏而产生的阴影效果。何况业界普遍认为地形渲染的精度是低于室内渲染一个档次的(新游戏FarCry是个例外)。更妙的是,顶点光照信息可以存储在高度图里,我们把高度点从一个unsigned char改为一个多字节的数据结构:struct HeightPoint unsigned char height; / 用于计算定点的Y坐标值,用于渲染地形高度起伏 unsigned char alpha; / 定点diffuse的alpha,用于多层纹理混合 unsigned char red; / 顶点diffuse的red,用于光照 unsigned char green; / 顶点diffuse的green,用于光照 unsigned char blue; / 顶点diffuse的blue,用于光照;这样高度图信息不仅包含高度信息,也包含多层纹理混合信息、光照信息。当动态创建地形的时候,在读取高度数据的同时也能得到与该顶点对应的diffuse值,非常方便。下面是用DX自带的MFCTex程序验证理论。3个TextureStage正是使用上面所说的设置方法。 图1env2.bmp是一个砖墙的贴图,caust11.tga是一个水面波纹的贴图,env3.bmp没有被使用。Diffuse颜色是0x77ff0000,是纯红色,但alpha值为119。Stage0把env2.bmp的图像数据原封不动的保留给Stage1。Stage1的COLOROP使用D3DTOP_BLENDDIFFUSEALPHA的方法,以diffuse的alpha值(119 = 0.53)为混合因子混合caust11.tga和env2.bmp,公式是:ResultOfStage1 = caust11.tga * 0.53 + env2.bmp * (1 0.53),得到的视觉结果是我们既能看到砖墙又能看到水面波纹,他们被半透明的混合起来了。Stage2使用相乘,把diffuse的RGB三分量与ResultOfStage1(Current就是ResultOfStage1)上对应点的RGB三分量乘起来,由于diffuse的RGB是ff0000纯红色,完全没有green和blue分量,所以这次得到的视觉结果是整个墙壁偏红色。这样我们就产生了墙壁上被投上了水面折射的波纹,而整个墙壁又被一片红光照亮的效果。下面来看看Torque引擎、极限滑雪的地形贴图渲染效果。首先是Torque。Torque引擎的Demo所使用的纹理文件都没有打包,所以我很容易找到这些文理,用Photoshop给它们画上标记,再到游戏中看他们是如何被混合、以及怎样贴到地面上去。这个Demo只用了3张地形纹理:1个grass.jpg,1个sand.jpg,1个patchy.jpg。每张纹理我先用红色粗线条勾出它的4条边,再在左上角和右下角用写上它的文件名,我还给它们写上中文译名,grass.jpg是“草”,sand.jpg是“沙”,patchy.jpg是“稀疏的草地”。来看截图: 图2每张地形纹理都是256*256的,从空中这个角度看,每张纹理都被映射到地形上一个相当大的方形区域,所以镜头贴近地面的时候,会变得很模糊,但Torque会在这时贴上细节纹理(参见后面的截图),一个叫detail1.png的图片文件(还是只有1张,但效果很好),这是另一个技术了,在此不表。图中,凡是黄色区域都来自sand.jpg。我们看那个左边有“稀疏的草地”的方形区域,这个区域用的是patchy.jpg和sand.jpg两张纹理混合的,“地”字就刚好位于混合边界,所以模糊了。混合因子不是顶点diffuse的alpha吗?所以这个区域里面,要有更多的顶点,没问题,Torque使用四叉树来创建地形,这个方形区域里面被细分为更小的方形区域,而且不是平衡的(LOD技术),所以有足够的顶点,同时看上去混合边界是扭曲的。这个Demo可以切换为线框渲染模式,我好好观察了那些顶点的分布,确实跟Alpha混合的分布相一致。再来一张截图: 图3从这个截图里面看出,阴影的存在确实起到了丰富视觉效果的作用。看左边那个方形区域,几乎全是沙地,但有阴影的存在,效果就好多了。你可能觉得它的阴影很细致,但别忘了这是一个全3D的FPS游戏,我是在很高的空中俯拍的。另一个游戏极限滑雪,这是欧洲某个国家制作的商业游戏。虽是商业游戏,它的纹理文件也没有打包,赤裸裸的jpg、tga,所以我把这些纹理都替换为只有一个颜色的图片,再勾勒出图片的四条边,打上文件名。由于是个滑雪游戏,所以场景中最常见的颜色就是白色了,所以大范围内只使用同一张纹理用得理直气壮。 图4当然要加上阴影,不然真的会灼伤玩家的眼睛呢。有了阴影,效果好一些了。再加上彩色的光影,还蛮令人着迷的,看图: 图5游戏中的山头和公路都需要别的纹理来混合。 图6看图6的阴影,尤其是左边的,有较为明显的梯级,右边的呈矩形,应该是那棵树的影子,但却很涣散,很不对劲,跟顶点光照的效果十分相像,可能是场景编辑器把计算出来的影子信息存储到顶点的diffuse中去了。这个游戏的雪地纹理只有2张,另一张出现的频率较小。 SetTextureStageState: HRESULT SetTextureStageState( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value ); stage这个参数是指第几层纹理,,, 这个版本的dx最多支持9层纹理。 Type:Defines the type of operation that a texture stage will perform./定义对该纹理的哪个属进行设置,值很多。 Value: 指的是前面所选属性的值type: D3DTSS_ALPHAOP = 4, /alpha通道的运算, D3DTSS_COLOROP = 1, /颜色的运算 /这里的op 是operations,指对前面设置的颜色进行运算 /既后面的2个type:D3DTSS_COLORARG1,D3DTSS_COLORARG2 /或D3DTSS_ALPHAARG1,D3DTSS_ALPHAARG2 = 6value: D3DTOP_DISABLE = 1, /该纹理无效,既不显示 D3DTOP_SELECTARG1 = 2, /选择第1个颜色值(既D3DTSS_COLORARG1的值)作为纹理颜色输出 D3DTOP_SELECTARG2 = 3, /选择第2个颜色值(既D3DTSS_COLORARG2的值)作为纹理颜色输出 D3DTOP_MODULATE = 4, /将颜色1和颜色2相乘作为纹理颜色输出 D3DTOP_MODULATE2X = 5, /将颜色1和颜色2相乘后左移1bit(用于增亮)作为纹理颜色输出 , D3DTOP_MODULATE4X = 6, /将颜色1和颜色2相乘后左移2bit(用于增亮)作为纹理颜色输出 D3DTOP_ADD = 7, /将颜色1和颜色2相加作为纹理颜色输出 D3DTOP_ADDSIGNED = 8, /后面的参见SDK 都是对2个颜色进行运算 D3DTOP_ADDSIGNED2X = 9, D3DTOP_SUBTRACT = 10, D3DTOP_ADDSMOOTH = 11, D3DTOP_BLENDDIFFUSEALPHA = 12, D3DTOP_BLENDTEXTUREALPHA = 13, D3DTOP_BLENDFACTORALPHA = 14, D3DTOP_BLENDTEXTUREALPHAPM = 15, D3DTOP_BLENDCURRENTALPHA = 16, D3DTOP_PREMODULATE = 17, D3DTOP_MODULATEALPHA_ADDCOLOR = 18, D3DTOP_MODULATECOLOR_ADDALPHA = 19, D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, D3DTOP_BUMPENVMAP = 22, D3DTOP_BUMPENVMAPLUMINANCE = 23, D3DTOP_DOTPRODUCT3 = 24, D3DTOP_MULTIPLYADD = 25, D3DTOP_LERP = 26, D3DTOP_FORCE_DWORD = 0x7fffffff, type: D3DTSS_COLORARG1 = 2, D3DTSS_COLORARG2 = 3, D3DTSS_ALPHAARG1 = 5, D3DTSS_ALPHAARG2 = 6, D3DTSS_COLORARG0 = 26, D3DTSS_ALPHAARG0 = 27, D3DTSS_RESULTARG = 28,value: 这里的TA指的是texture arguments , D3DTA_CONSTANT /给当前纹理一个固定的值; D3DTA_DIFFUSE; /diffuse的值作为参数 diffuse 可能有多个来源。比如材质,vertex D3DTA_SELECTMASK /Mask value for all arguments; not used when setting texture arguments 这句话不理解啊,为什么要伪装呢 D3DTA_SPECULAR /取spercular 的值作为参数 来源同diffuse D3DTA_TEMP /待定。 D3DTA_TEXTURE /用纹理的颜色值作为参数 D3DTA_TFACTOR /待定。高程地形纹理首先我们载入一个32*32灰度图其图中的每一位表示高程中的一个栅格的位置,由此确定每一栅格位置处的高度。定义一个地图图像数据 unsigned char * imageData;/地形图图像数据/#define BITMAP_ID 0x4D42/全球位图标示ID #define MAP_Z 32;/灰度图在Z轴上的尺寸#define MAP_X 32;/灰度图在X轴上的尺寸#define MAP_SCALE 20.0f;/地形图的尺度比例因子#define PI 3.14159;/PI常量/Include#include#include#include#include#include/标准OPENGL函数库#include/OPENGL实用函数库/全局变量HDC g_HDC;bool fullscreen = false;bool KeyPressed256;float angle = 0.0f;/视点角度float radians = 0.0f;/以弧度表示视点角度float waterHeight = 154.0f/水面高度bool waterDir = true;/用于水动画,true 向上,false 向下/鼠标视点变量int mouseX,mouseY;/鼠标坐标float camerX,camerY,camerZ;/视点坐标float lookX,lookY,lookZ;/观察点坐标/纹理信息BITMAPINFOHEADER bitmapInfoHeader;/临时位图信息头BITMAPINFOHEADER landInfo;/陆地纹理信息头BITMAPINFOHEADER waterInfo;/水纹理信息头unsigned char* imageData;/地形图图像数据unsigned char* landTexture;/陆地纹理数据unsigned char* waterTexture;/水纹理数据unsigned int land /陆地纹理对象unsigned int water/水纹理对象/地形数据float terrainMAP_ZMAP_X3/遍历所有的高程点,并为每个点计算坐标void InitializeTerrain() for(int z = 0;zMAP_Z;z+) for(int x = 0;xMAP_X;x+) terrainxz0 = float(x)*MAP_SCALE; terrainxz1 = (float)imageData(z*MAP_Z+x)*3; terrainxz3 = -float(z)*MAP_SCALE; /载入纹理数据并绑定bool LoadTextues() /载入陆地纹理地形 landTexture = LoadBitmapFile(green.bmp,&landInfo); if(!landTexture) return false; waterTexture = LoadBitmapFile(water.bmp,&waterInfo); if(!waterTexture) retrun false; /生成陆地纹理mipmap glGenTextures(1,&land); glBindText(GL_TEXTURE_2D,land); glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); gluBuild2DMipmape(GL_TEXTURE_2D,GL_RGB,landInfo.biWidth, landInfo.biHeigh,GL_RGB,GL_UNSIGNED_BYTE,landTexture); /生成水的纹理 glGenTextures(1,&water); glBindText(GL_TEXTURE_2D,water); glTextParameTeri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTextParameTeri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTextParameTeri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTextParameTeri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); gluBuild2DMipmape(GL_TEXTURE_2D,GL_RGB,waterInfo.biWidth, waterInfo.biHeigh,GL_RGB,GL_UNSIGNED_BYTE,waterTexture); retrue true;void Render() radians = float(PI*(angle-90.0f)/180.0f; /计算视点的位置 camerX = lookX + sin(radians)*mouseY; camerZ = lookZ + cos(radians)*mouseY; camerY = lookY + mousY/2.0f; /将视点的观察点设为地形图的中央 lookX = (MAP_X*MAP_SCALE)/2.0f; lookY = 150.0f; lookZ = -(MAP_Z*MAP_SCALE)/2.0f; /清理屏幕和深度缓存 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); /设置视点的位置 gluLookAt(camerX,camerY,camerZ,lookX,lookY,lookZ,0.0,1.0,0.1); /将当前纹理设为陆地纹理 glBindTexture(GL_TEXTURE_2D,land);/遍历所有地形数据点/但只为沿X轴绘制每一条三角形带for(int z=0; zMAP_Z-1,z+) glBegin(GL_TRIANGLE_STRIP) for(int x=0;x1 / / / / / / / / / / / 2 -3 /绘制顶点0 glColor3f(terrainxz1/255.0f,tereainxz1/255.0f,terrainxz1/255.0f); glTexCoord2f(0.0f,0.0f);/纹理 glVertex3f(terrainxz0,terrainxz1,terrainxz2); /绘制顶点1 glColor3f(terrainx+1z1/255.0f,terrainx+1z1/255.0f,terrainx+1z 1/255.0f); glTexCoord2f(1.0f,0.0f); glVertex3f(terrainx+1z0,terrainx+1z1,terrainx+1z2); /绘制顶点2 glColor3f(terrainxz+11/255.0f,terrainxz+11/255.0f,terrainx+1z 1/255.0f); glTexCoord2f(0.0f,1.0f); glVertex3f(terrainxz+10,terrainxz+11,terrainxz+12); /绘制顶点3 glColor3f(terrainx+1z+11/255.0f,terrainx+1z+11/255.0f,terrainx+1 z+11/255.0f); glTexCorrd2f(1.0f,1.0f); glVertex3f(terrainx+1y+10,terrainx+1y+11,terrainx+1y+12); glEnd(); /启用混合 glEnable(GL_BLEND); /将深度设为只读状态 glDepthMask(GL_FALSE); /设置用于透明效果的混合因子 glBlendFunc(GL_SRC_ALPHA,GL_ONE); glColor4f(0.5f,0.5f,1.0f,0.7f);/将颜色设置为透明的蓝色 glBindTexture(GL_TEXTURE_2D,water);/将水纹理设置为当前纹理, glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3f(terrain000,waterHeight,terrain002); glTexCoord2f(10.0f,0.0f); glVertex3f(terrainMAX_X-100,waterHeight,terrainMAX_X-102); glTexCoord2f(10.0f,10.0f); glVertex3f(terrainMAX_X-1MAX_Z-10,waterHeight,terrainMAX_X-1MAX_Z-12); glTexCoord2f(0.0f,10.0f); glVertex3f(

温馨提示

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

最新文档

评论

0/150

提交评论