无限大地图 研究
实现无限大地图没有想象中那么难 今天尝试性的写了一下, 一个下午时间耗费了, 东西出来了, 效果不错, 点滴心得在此说一下 实现无限大地图, 说白了其实就是只绘制眼前的物体, 我们把这个扩展一下, 只要能实现一个地图能够沿着我们预想的轨道衍生, 并且删除已经走过去的部分, 这样的话, 其实顶点的个数还是没变, 那么什么变了呢, 明白人一想就知道, 是点本身变了 由于是试验, 所以我不必要用四叉树来进行一个完整的遍历过程, 用树组足够, 当然, 我用四叉树早已实现了足够大地图, 现在我要写的是无限大地图 我用一个二维树组来存储点 代码如下 CUSTOMVERTEX* vertices = new CUSTOMVERTEX[heightcount * widthcount]; int index = 0; int indindex[100][100]; for( int i=0; i<heightcount; i++ ) { for( int j=0; j<widthcount; j++ ) { tvertices[j].position = D3DXVECTOR3( -width*(float)widthcount/2 + width*j + width/2, (float)(rand()%100)/50, height*(float)heightcount/2 - height*i - height/2 ); tvertices[j].normal = normal; tvertices[j].tu = j%2; tvertices[j].tv = i%2; vertices[index] = tvertices[j]; indindex[j] = index; index++; } } /* 说明一下, 我在这用了一个全局的二维树组来存储要画的点, 也就是我们可见的点 这个变量名是 tvertices[][], 而后面的只是很一般的索引点的创建和存入缓冲区 */ int indcount = 0; WORD* indices = new WORD[(widthcount-1)*(heightcount-1)*6]; for( int i=0; i<heightcount-1; i++ ) { for( int j=0; j<widthcount-1; j++ ) { indices[indcount++] = indindex[j]; indices[indcount++] = indindex[j][i+1]; indices[indcount++] = indindex[j+1]; indices[indcount++] = indindex[j+1]; indices[indcount++] = indindex[j][i+1]; indices[indcount++] = indindex[j+1][i+1]; } } size_vertices = widthcount * heightcount * sizeof(CUSTOMVERTEX); size_index = (widthcount-1) * (heightcount-1) * 6 * sizeof( WORD ); //创建顶点缓存区,并获取接口IDirect3DVertexBuffer9的指针 pd3dDevice->CreateVertexBuffer( size_vertices, 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &g_pVB, NULL ); //把顶点数据填入顶点缓存区 VOID* pVertices; g_pVB->Lock( 0,size_vertices,(void**)&pVertices,0 ); memcpy( pVertices,vertices,size_vertices ); g_pVB->Unlock(); //创建索引缓存区,并获取接口LPDIRECT3DINDEXBUFFER9的指针 pd3dDevice->CreateIndexBuffer( size_index, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &g_pIB, NULL ); //把索引值填入索引缓存区 VOID* pIndices; g_pIB->Lock( 0,size_index,(void**)&pIndices,0 ); memcpy( pIndices,indices,size_index ); g_pIB->Unlock(); 到此, 所有的创建工作已经完成, 我将会对这些点进行适当的变换 看下面的代码 CUSTOMVERTEX* verticesTemp; g_pVB->Lock( 0,size_vertices,(void**)&verticesTemp,0 ); int index = 0; //将前方的地形第一排的点进行重置 for( int w=0; w<widthcount; w++ ) { verticesTemp[index].position = D3DXVECTOR3( -width*(float)widthcount/2 + width*w + width/2, (float)(rand()%100)/50, tvertices[0][0].position.z + height ); verticesTemp[index].tu = tvertices[0][w].tu; verticesTemp[index].tv = 1 - tvertices[0][w].tv; index++; } //紧接着, 我将地形后面的部分连接上来, 而最后一派的顶点, 会散落在内存里, 当然, 这里是不需要释放的, 因为我始终控制的只是我可见的那部分点 for( int i=0; i<heightcount-1; i++ ) { for( int j=0; j<widthcount; j++ ) { verticesTemp[index] = tvertices[j]; index++; } } 到此, 代码基本完成, 后面有些附加工作要进行 if( DXUTIsKeyDown( VK_UP ) ) { ViewPos.z += 0.01; if( (int)(ViewPos.z * 100)%50 == 0 ) ExternTerrain(); } 在控制中, 我本来用的camera的移动速度是1.0, 不过这样太快, 没有层次感, 于是我缩小了100倍, 同时让他与地形的变换同步, 这里ExternTerrain()就是前面的那部分顶点变换的函数 运行起来效果也不错, 这里我只列举出了一个方向的衍生, 然后, 添加8个方向的衍生, 这里用树组真是绰绰有余, 当然, 如果要更好的渲染效果建议还是用四叉树 宇多田崴笔 2005-10-19 晚 联系方式 QQ: 24387124 MSN: Utada_Wei@msn.com WEB: www.lowgame.com ICQ: 122032327 欢迎讨论 |