Ogre 天龙八部地形管理器(2) --- 地形和静态对象的加载

参考他人的文章
修改 ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
纹理的创建方法和该文一样, 只是我打不算用ETM管理器创建地形
自己创建一个mesh来管理地形, 包含顶点数据, 纹理数据
  1  void  TLBBTerrain::createManualMesh()
  2  {
  3 
  4      MeshPtr mesh  =  MeshManager::getSingleton().createManual( " mymesh " ,
  5          ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
  6      SubMesh *  submesh  =  mesh -> createSubMesh();
  7      submesh -> useSharedVertices  =   false ;
  8 
  9       //  顶点缓存
 10      submesh -> vertexData  =   new  VertexData();
 11      submesh -> vertexData -> vertexStart  =   0 ;
 12      unsigned  int  nCount  =  m_xSize  *  m_zSize  *   4 ;
 13      submesh -> vertexData -> vertexCount  =  nCount;
 14 
 15      VertexDeclaration *  decl  =  submesh -> vertexData -> vertexDeclaration;
 16      VertexBufferBinding *  bind  =  submesh -> vertexData -> vertexBufferBinding;
 17 
 18      size_t offset  =   0 ;
 19      decl -> addElement(MAIN_BINDING, offset, VET_FLOAT3, VES_POSITION);
 20      offset  +=  VertexElement::getTypeSize(VET_FLOAT3);
 21 
 22      decl -> addElement(MAIN_BINDING, offset, VET_FLOAT3, VES_NORMAL);
 23      offset  +=  VertexElement::getTypeSize(VET_FLOAT3);
 24 
 25      decl -> addElement(MAIN_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES,  0 );
 26      offset  +=  VertexElement::getTypeSize(VET_FLOAT2);
 27 
 28      decl -> addElement(MAIN_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES,  1 );
 29      offset  +=  VertexElement::getTypeSize(VET_FLOAT2);
 30 
 31      decl -> addElement( MAIN_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES,  2 );
 32      offset  +=  VertexElement::getTypeSize(VET_FLOAT2);
 33 
 34      HardwareVertexBufferSharedPtr vertexBuffer  =  HardwareBufferManager::getSingleton().createVertexBuffer(
 35          decl -> getVertexSize(MAIN_BINDING), nCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
 36      bind -> setBinding(MAIN_BINDING, vertexBuffer);
 37 
 38       float *  pBase  =  static_cast < float *> (vertexBuffer -> lock (HardwareBuffer::HBL_DISCARD));
 39 
 40      TexureInfo info;
 41 
 42       for  ( int  j  =   0 ; j  <  m_zSize;  ++ j)
 43      {
 44           for  ( int  i  =   0 ; i  <  m_xSize;  ++ i)
 45          {
 46              info  =  handleTexture(i, j);
 47 
 48               //  点0
 49              fillVertexData(i, j, pBase, info.firstleft, info.firsttop, info.secondleft, info.secondtop);
 50              pBase  +=   12 ;
 51 
 52               //  点1
 53              fillVertexData(i, j + 1 , pBase, info.firstleft, info.firstbottom, info.secondleft, info.secondbottom);
 54              pBase  +=   12 ;
 55 
 56               //  点2
 57              fillVertexData(i + 1 , j + 1 , pBase, info.firstright, info.firstbottom, info.secondright, info.secondbottom);
 58              pBase  +=   12 ;
 59 
 60               //  点3
 61              fillVertexData(i + 1 , j, pBase, info.firstright, info.firsttop, info.secondright, info.secondtop);
 62              pBase  +=   12 ;
 63          }
 64      }
 65 
 66      vertexBuffer -> unlock();
 67 
 68      HardwareIndexBufferSharedPtr indexBuffer  =
 69          HardwareBufferManager::getSingleton().createIndexBuffer(
 70          HardwareIndexBuffer::IT_32BIT,
 71          m_xSize  *  m_zSize  *   6 ,
 72          HardwareBuffer::HBU_STATIC,  true );
 73 
 74      submesh -> indexData -> indexBuffer  =  indexBuffer;
 75      submesh -> indexData -> indexStart  =   0 ;
 76      submesh -> indexData -> indexCount  =  m_xSize  *  m_zSize  *   6 ;
 77      unsigned  int *  indexBuff  =  (unsigned  int * )indexBuffer -> lock (HardwareBuffer::HBL_NORMAL);
 78       int  indexFirstNum  =   0 ;
 79       for  ( int  j  =   0 ; j  <  m_zSize;  ++ j)
 80      {
 81           for  ( int  i  =   0 ; i  <  m_xSize;  ++ i)
 82          {
 83               * indexBuff ++   =  indexFirstNum;
 84               * indexBuff ++   =  indexFirstNum  +   1 ;
 85               * indexBuff ++   =  indexFirstNum  +   2 ;
 86 
 87               * indexBuff ++   =  indexFirstNum;
 88               * indexBuff ++   =  indexFirstNum  +   2 ;
 89               * indexBuff ++   =  indexFirstNum  +   3 ;
 90              indexFirstNum  +=   4 ;
 91          }
 92      }
 93 
 94      indexBuffer -> unlock();
 95 
 96      AxisAlignedBox meshBounds( 0 , m_minHeight  *  m_scale.y,  0 ,
 97          m_xSize  *  m_scale.x, m_maxHeight  *  m_scale.y, m_zSize  *  m_scale.z);
 98      mesh -> _setBounds(meshBounds);
 99      mesh -> load();
100      mesh -> touch();
101 
102       //  设置相机位置
103      mSceneMgr -> getCamera( " PlayerCam " ) -> setPosition( 0 , m_maxHeight  *  m_scale.y,  0 );
104  }

其实我认为, 可以根据主角在场景的位置创建小范围的mesh, 可以将该mesh分成tile*tile大小, 根据主角位置创建周围四个tile的mesh就可以了. 不需要写这么大的mesh.等以后写入主角怪物的时候在写这段代码

加载静态对象的时候出现了很多问题, 经过分析, 发现天龙八部游戏新版本的很多mesh不能够直接使用, 主要是Model目录里面的0灌木, 0树木, 0物品三个文件夹里面的mesh文件
直接拷贝老天龙的数据就可以了
不过加载的时候读取skeleton数据会出现错误, 查找一些资料后发现需要直接修改Ogre源码, 这些数据主要用于实现骨骼动画的时候会出现
对OgreSkeletonSerializer.cpp文件里面的SkeletonSerializer::readAnimationTrack 函数进行修改.然后编译出ogremain.dll, ogremain_d.lib, 覆盖OgreSDK/bin文件里面的同名文件

 1  void    SkeletonSerializer::readAnimationTrack(DataStreamPtr   &    stream, Animation   *    anim,
 2         Skeleton  *   pSkel)
 3     {
 4           //   unsigned short boneIndex     : Index of bone to apply to
 5         unsigned   short   boneHandle;
 6         readShorts(stream,   &  boneHandle,   1  );
 7 
 8           //   Find bone
 9         Bone   *  targetBone   =   pSkel  ->  getBone(boneHandle);
10 
11           //   Create track
12         NodeAnimationTrack  *   pTrack   =   anim  ->  createNodeTrack(boneHandle, targetBone);
13 
14           //   Keep looking for nested keyframes
15           if   (  !  stream  ->  eof())
16         {
17             unsigned   short   streamID   =   readChunk(stream);
18 
19               //  while(streamID == SKELETON_ANIMATION_TRACK_KEYFRAME && !stream->eof())
20               while  ((streamID   ==   SKELETON_ANIMATION_TRACK_KEYFRAME   ||   streamID   ==     0x4120  )   &&     !  stream  ->  eof())
21             {
22                   if   (streamID   ==     0x4120  )
23                 {
24                     unsigned   short   len;
25                     readShorts(stream,   &  len,   1  );
26                     unsigned   short   flags;
27                     readShorts(stream,   &  flags,   1  );
28 
29                       int   count   =   (mCurrentstreamLen   -     4     -     4  )   /     4  ;
30                       if   (len   !=   count   /     8  )
31                         len   =   len;
32                       float   time;
33                       for   (  int   i   =     0  ; i   <   len; i   +=     1  )
34                     {
35                         readFloats(stream,   &  time,   1  );
36                         TransformKeyFrame   *  kf   =   pTrack  ->  createNodeKeyFrame(time);
37 
38                         Quaternion rot   =   Quaternion::IDENTITY;
39                           if   (flags   &     1  )
40                         {
41                             readObject(stream, rot);
42                         }
43                         kf  ->  setRotation(rot);
44 
45                         Vector3 trans   =   Vector3::ZERO;
46                           if   (flags   &     2  )
47                         {
48                             readObject(stream, trans);
49                         }
50                         kf  ->  setTranslate(trans);
51                     }
52                 }
53                   else
54                     readKeyFrame(stream, pTrack, pSkel);
55 
56                   if   (  !  stream  ->  eof())
57                 {
58                       //   Get next stream
59                     streamID   =   readChunk(stream);
60                 }
61             }
62               if   (  !  stream  ->  eof())
63             {
64                   //   Backpedal back to start of this stream if we've found a non-keyframe
65                 stream  ->  skip(  -  STREAM_OVERHEAD_SIZE);
66             }
67 
68         }
69 
70     } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值