一直想用Ogre 1.8来实现一个拥有较高自由度的地形编辑Demo,在Ogre的地形sample中,只有一块Terrain,明显是满足不了地表纹理丰富的大型地形块的。于是,我的解决办法是,将加入的地形高度图分几个区域,每个区域以一个Terrain的形式加入,这样就生成了一个由多个Terrain组成的大地形,每个Terrain的纹理可以保持不同样式。

需要注意的是关于Ogre::Image的运用,用Image类动态生成图片,申请内存必须用Ogre申请内存的方式,如果用new,最后在释放内存的时候,会造成程序的崩溃。= =当时找这个BUG找的真悲剧。其实还有一个更好的实现方式吧,不用申请内存,直接在原高度图那里拿到需要的高度数据就行了,不过应该会比较麻烦,这里自己偷懒了。

View Code
 1 bool CImageSplitter::SplitterImage(const size_t x, const size_t y, const size_t width, const size_t height, Ogre::Image &ImageSource, Ogre::Image &ImageOut)
 2 {
 3     Ogre::PixelBox pb = ImageSource.getPixelBox();
 4 
 5     //划分区域
 6     Ogre::Box box;
 7     box.left = x;
 8     box.top = y;
 9     box.right = box.left + width;
10     box.bottom = box.top + height;
11 
12     //创建内存
13     size_t bit =  ImageSource.getBPP();
14     size_t ByteCount = bit/8;
15     Ogre::uchar *pImageBuffer = OGRE_ALLOC_T(Ogre::uchar, width * height * ByteCount, Ogre::MEMCATEGORY_GENERAL);
16     if(pImageBuffer == NULL)
17         return false;
18     Ogre::PixelBox NewPb = pb.getSubVolume(box);
19     Ogre::uchar *pCurrData = pImageBuffer;
20     Ogre::uchar *pFindData = reinterpret_cast<Ogre::uchar*>(NewPb.data);
21     for(int i = 0; i < height; ++i)
22     {
23         for(int j = 0; j < width; ++j)
24         {
25             size_t n = ByteCount;
26             while(n)
27             {
28                 *pCurrData++ = *pFindData++;
29                 --n;
30             }
31         }
32         pFindData += NewPb.getRowSkip();
33     }
34 
35     ImageOut.loadDynamicImage(pImageBuffer, width, height, 1, ImageSource.getFormat(), true);
36 
37     return true;
38 }

 

如果完成了这一步,接下来就是地表纹理的编辑了,待续...