Ogre 天龙八部地形管理器
2011-04-14 15:00
190 查看
最近研究天龙八部的地形管理, 由于地形很大, 很显然Ogre自带的地形管理器没法使用
参考了别人的研究之后, 不打算使用ETM来管理地形
直接写了一个巨大的手工纹理来保存地形所需要的所有图像, 然后根据网格数据一个一个填写纹理坐标,
目前只写了地形第一层的代码, 第二层还没开始
读写速度还是很快的
下面是两张截图
参考他人的文章
修改 ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
纹理的创建方法和该文一样, 只是我打不算用ETM管理器创建地形
自己创建一个mesh来管理地形, 包含顶点数据, 纹理数据
view sourceprint?
其实我认为, 可以根据主角在场景的位置创建小范围的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文件里面的同名文件
view sourceprint?
显示场景图如下
参考了别人的研究之后, 不打算使用ETM来管理地形
直接写了一个巨大的手工纹理来保存地形所需要的所有图像, 然后根据网格数据一个一个填写纹理坐标,
目前只写了地形第一层的代码, 第二层还没开始
读写速度还是很快的
下面是两张截图
参考他人的文章
修改 ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
纹理的创建方法和该文一样, 只是我打不算用ETM管理器创建地形
自己创建一个mesh来管理地形, 包含顶点数据, 纹理数据
view sourceprint?
01 | void TLBBTerrain::createManualMesh() |
02 | { |
03 | MeshPtr mesh = MeshManager::getSingleton().createManual( "mymesh" , |
04 | ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); |
05 | SubMesh* submesh = mesh->createSubMesh(); |
06 | submesh->useSharedVertices = false ; |
07 | // 顶点缓存 |
08 | submesh->vertexData = new VertexData(); |
09 | submesh->vertexData->vertexStart = 0; |
10 | unsigned int nCount = m_xSize * m_zSize * 4; |
11 | submesh->vertexData->vertexCount = nCount; |
12 | VertexDeclaration* decl = submesh->vertexData->vertexDeclaration; |
13 | VertexBufferBinding* bind = submesh->vertexData->vertexBufferBinding; |
14 | size_t offset = 0; |
15 | decl->addElement(MAIN_BINDING, offset, VET_FLOAT3, VES_POSITION); |
16 | offset += VertexElement::getTypeSize(VET_FLOAT3); |
17 | decl->addElement(MAIN_BINDING, offset, VET_FLOAT3, VES_NORMAL); |
18 | offset += VertexElement::getTypeSize(VET_FLOAT3); |
19 | decl->addElement(MAIN_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); |
20 | offset += VertexElement::getTypeSize(VET_FLOAT2); |
21 | decl->addElement(MAIN_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 1); |
22 | offset += VertexElement::getTypeSize(VET_FLOAT2); |
23 | decl->addElement(MAIN_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 2); |
24 | offset += VertexElement::getTypeSize(VET_FLOAT2); |
25 | HardwareVertexBufferSharedPtr vertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( |
26 | decl->getVertexSize(MAIN_BINDING), nCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); |
27 | bind->setBinding(MAIN_BINDING, vertexBuffer); |
28 | float * pBase = static_cast < float *>(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); |
29 | TexureInfo info; |
30 | for ( int j = 0; j < m_zSize; ++j) |
31 | { |
32 | for ( int i = 0; i < m_xSize; ++i) |
33 | { |
34 | info = handleTexture(i, j); |
35 | // 点0 |
36 | fillVertexData(i, j, pBase, info.firstleft, info.firsttop, info.secondleft, info.secondtop); |
37 | pBase += 12; |
38 | // 点1 |
39 | fillVertexData(i, j+1, pBase, info.firstleft, info.firstbottom, info.secondleft, info.secondbottom); |
40 | pBase += 12; |
41 | // 点2 |
42 | fillVertexData(i+1, j+1, pBase, info.firstright, info.firstbottom, info.secondright, info.secondbottom); |
43 | pBase += 12; |
44 | // 点3 |
45 | fillVertexData(i+1, j, pBase, info.firstright, info.firsttop, info.secondright, info.secondtop); |
46 | pBase += 12; |
47 | } |
48 | } |
49 | vertexBuffer->unlock(); |
50 | HardwareIndexBufferSharedPtr indexBuffer = |
51 | HardwareBufferManager::getSingleton().createIndexBuffer( |
52 | HardwareIndexBuffer::IT_32BIT, |
53 | m_xSize * m_zSize * 6, |
54 | HardwareBuffer::HBU_STATIC, true ); |
55 | submesh->indexData->indexBuffer = indexBuffer; |
56 | submesh->indexData->indexStart = 0; |
57 | submesh->indexData->indexCount = m_xSize * m_zSize * 6; |
58 | unsigned int * indexBuff = (unsigned int *)indexBuffer->lock(HardwareBuffer::HBL_NORMAL); |
59 | int indexFirstNum = 0; |
60 | for ( int j = 0; j < m_zSize; ++j) |
61 | { |
62 | for ( int i = 0; i < m_xSize; ++i) |
63 | { |
64 | *indexBuff++ = indexFirstNum; |
65 | *indexBuff++ = indexFirstNum + 1; |
66 | *indexBuff++ = indexFirstNum + 2; |
67 | *indexBuff++ = indexFirstNum; |
68 | *indexBuff++ = indexFirstNum + 2; |
69 | *indexBuff++ = indexFirstNum + 3; |
70 | indexFirstNum += 4; |
71 | } |
72 | } |
73 | indexBuffer->unlock(); |
74 | AxisAlignedBox meshBounds(0, m_minHeight * m_scale.y, 0, |
75 | m_xSize * m_scale.x, m_maxHeight * m_scale.y, m_zSize * m_scale.z); |
76 | mesh->_setBounds(meshBounds); |
77 | mesh->load(); |
78 | mesh->touch(); |
79 | // 设置相机位置 |
80 | mSceneMgr->getCamera( "PlayerCam" )->setPosition(0, m_maxHeight * m_scale.y, 0); |
81 | } |
加载静态对象的时候出现了很多问题, 经过分析, 发现天龙八部游戏新版本的很多mesh不能够直接使用, 主要是Model目录里面的0灌木, 0树木, 0物品三个文件夹里面的mesh文件
直接拷贝老天龙的数据就可以了
不过加载的时候读取skeleton数据会出现错误, 查找一些资料后发现需要直接修改Ogre源码, 这些数据主要用于实现骨骼动画的时候会出现
对OgreSkeletonSerializer.cpp文件里面的SkeletonSerializer::readAnimationTrack 函数进行修改.然后编译出ogremain.dll, ogremain_d.lib, 覆盖OgreSDK/bin文件里面的同名文件
view sourceprint?
01 | void SkeletonSerializer::readAnimationTrack(DataStreamPtr &stream, Animation *anim, |
02 | Skeleton * pSkel) |
03 | { |
04 | // unsignedshort boneIndex : Index of bone to apply to |
05 | unsigned short boneHandle; |
06 | readShorts(stream, & boneHandle, 1 ); |
07 | // Find bone |
08 | Bone * targetBone = pSkel -> getBone(boneHandle); |
09 | // Create track |
10 | NodeAnimationTrack * pTrack = anim -> createNodeTrack(boneHandle, targetBone); |
11 | // Keep looking for nested keyframes |
12 | if (! stream -> eof()) |
13 | { |
14 | unsigned short streamID = readChunk(stream); |
15 | // while(streamID == SKELETON_ANIMATION_TRACK_KEYFRAME && !stream->eof()) |
16 | while ((streamID == SKELETON_ANIMATION_TRACK_KEYFRAME || streamID ==0x4120 ) &&! stream -> eof()) |
17 | { |
18 | if (streamID ==0x4120 ) |
19 | { |
20 | unsigned short len; |
21 | readShorts(stream, & len, 1 ); |
22 | unsigned short flags; |
23 | readShorts(stream, & flags, 1 ); |
24 | int count = (mCurrentstreamLen -4-4 ) /4 ; |
25 | if (len != count /8 ) |
26 | len = len; |
27 | float time ; |
28 | for ( int i =0 ; i < len; i +=1 ) |
29 | { |
30 | readFloats(stream, & time , 1 ); |
31 | TransformKeyFrame * kf = pTrack -> createNodeKeyFrame( time ); |
32 | Quaternion rot = Quaternion::IDENTITY; |
33 | if (flags &1 ) |
34 | { |
35 | readObject(stream, rot); |
36 | } |
37 | kf -> setRotation(rot); |
38 | Vector3 trans = Vector3::ZERO; |
39 | if (flags &2 ) |
40 | { |
41 | readObject(stream, trans); |
42 | } |
43 | kf -> setTranslate(trans); |
44 | } |
45 | } |
46 | else |
47 | readKeyFrame(stream, pTrack, pSkel); |
48 | if (! stream -> eof()) |
49 | { |
50 | // Get next stream |
51 | streamID = readChunk(stream); |
52 | } |
53 | } |
54 | if (! stream -> eof()) |
55 | { |
56 | // Backpedal back to start of this stream if we've found a non-keyframe |
57 | stream -> skip(- STREAM_OVERHEAD_SIZE); |
58 | } |
59 | } |
60 | } |
相关文章推荐
- Ogre 天龙八部地形 Heightmap(高度图)+GridInfo(地表信息)初步结果
- Ogre的分页大地形场景管理器PLSM2使用手记
- Ogre的分页大地形场景管理器PLSM2使用手记
- 修改ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
- (转)修改ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
- Ogre渲染优化心得(三) -- 优化天龙八部的地形
- 修改ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
- 修改ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
- 转:修改ETM,用Ogre实现《天龙八部》地形与部分场景详解
- Ogre渲染优化心得(三) -- 优化天龙八部的地形
- 修改ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
- Ogre的分页大地形场景管理器PLSM2使用手记
- Ogre 天龙八部地形 Heightmap(高度图)+GridInfo(地表信息)初步结果
- 修改ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
- Ogre 天龙八部地形 Heightmap(高度图)+GridInfo(地表信息)初步结果
- 修改ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
- 武侠世界,基于Ogre的地形分析
- Ogre 天龙八部frame格式的帧动画
- 编写Ogre自定义场景管理器插件的方法
- 转:OGRE场景管理器介绍