一直想用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 }
如果完成了这一步,接下来就是地表纹理的编辑了,待续...