无限大地图研究 

2006-12-08 11:47 发布

2917 0 0
无限大地图 研究

实现无限大地图没有想象中那么难

今天尝试性的写了一下, 一个下午时间耗费了, 东西出来了, 效果不错, 点滴心得在此说一下

实现无限大地图, 说白了其实就是只绘制眼前的物体, 我们把这个扩展一下, 只要能实现一个地图能够沿着我们预想的轨道衍生, 并且删除已经走过去的部分, 这样的话, 其实顶点的个数还是没变, 那么什么变了呢, 明白人一想就知道, 是点本身变了

由于是试验, 所以我不必要用四叉树来进行一个完整的遍历过程, 用树组足够, 当然, 我用四叉树早已实现了足够大地图, 现在我要写的是无限大地图

我用一个二维树组来存储点

代码如下

 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
欢迎讨论

楼主新帖

TA的作品 TA的主页
B Color Smilies

你可能喜欢

无限大地图研究 
联系
我们
快速回复 返回顶部 返回列表