地形的网格可以使用高度图作为数据源生成。高度图可以是位图,可理解成二维数组,地形实际上就是一系列高度不同的网格而已,这样数组中每个元素的索引值刚好可以用来定位不同的网格(x,z),而所储存的值就是网格的高度(y)。
地形的渲染可由四叉树来管理,网格的每个顶点对应四叉树的各个节点,有关四叉树的应用可参考"引擎技术研究之场景管理------四叉树与视椎剔除技术"。
现讨论地形技术的相关应用:
一:地形的生成
1 根据一指定路径的灰度图生成高度图mpBmpHeightMap,并获取mpBmpHeightMap的长度length和宽度width
2 根据length和width创建一顶点指针mpVertexsMap,mpVertexsMap保存地形网格各顶点的位置。调用IDirect3DDevice9的
CreateVertexBuffer((width+1)*(length+1)*sizeof(Vertex),0,
D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1,D3DPOOL_MANAGED,&m_pVB, NULL)
生成顶点缓冲m_pVB,内存大小为(width+1)*(length+1)*sizeof(Vertex),
执行m_pVB->Lock( 0, 0, (void**)&vertex, 0 )锁定顶点缓冲,vertex指向其内存地址。
3 遍历Vertex每个顶点,并计算其位置x, y, z值,其中高度值y可由高度生成函数获取。并将Vertex的每个顶点值传递给mpVertexsMap数组,mpVertexsMap作用在于解除顶点锁定后仍可以使用顶点的位置值。调用IDirect3DDevice9的
CreateIndexBuffer(width*length*2*3*sizeof(DWORD),0,
D3DFMT_INDEX32, D3DPOOL_MANAGED,&m_pIB,NULL)
生成索引缓冲m_pIB,其大小为 width * length*2*3*sizeof(DWORD).
在地形信息更新时执行m_pIB->Lock( 0, 0, (void**)&index, 0 )锁定索引缓冲区,index指向其内存地址。
4 为地形设置纹理,并根据地形网格中外围四个顶点的索引及其位置创建四叉树。
至此,已根据四叉树生成地形网格。
二:地形的剔除
与一般模型的剔除不同,地形剔除技术指的是剔除视椎外的地形区域,即只在视椎内的区域绘制三角形。我们把地形在X,Z平面上划分成均匀大小的16 X 16个块,块的个数可由四叉树的层数决定,本例中层数为4,即有256个节点,每一节点对应一块。每一块包含多个网格,每块的网格数等于地形灰度图像素数除以块数:512 X 512/256=1024,即每块都是32X32的网格。每个网格可划分为两个三角形,即每块有2048个三角形。网格通过顶点索引所组成的三角形描述其所在的一片区域。整个地形用一棵四叉树把这些块组织起来。实时渲染时四叉树负责地形的裁剪,决定哪些块应该绘制,从而得到整个地形要渲染的三角形面片。地形的数据组织如图所示: