Ogre1.7的地形、天空與霧
ogre過去在地形的支持上很少,過去隻是讓你導入一個高度圖,然後在上麵放一層基本紋理和一細節紋理,在1.7版本的Ogre後,裏麵單獨加入了terrain的模塊,在地形的支持上已經非常強大,關於新版Ogre的地形的資料少之又少,我花了好幾天經過反複試驗根係摸了一下,總結一下新版Ogre的地形使用
1.設置攝像機的遠剪裁麵為無限遠
if (root->getRenderSystem()->getCapabilities()->hasCapability(Ogre::RSC_INFINITE_FAR_PLANE))
{
cam->setFarClipDistance(0); // enable infinite far clip distance if we can
}
2.設置TerrainGlobalOptions,這是一個表示地形的總體特性的類,他可以設置地形的一些特征,首先你需要new出來一個
mTerrainGlobals=new TerrainGlobalOptions();
然後設置一些必要的特征
mTerrainGlobals->setMaxPixelError(8);
這個值越小地形越精確,效率越低
在地形的渲染中。Ogre提供了一種組合貼圖的渲染,就是在較遠的地方使用一種貼圖混合簡單光影的方式來代替實際的紋理,這有很多應用:
1是這樣可以再較遠的地方不使用精細的紋理生成,提高效率
2是你可以使用這個特性實現遊戲中照亮與黑暗的效果
下麵是設置這方麵的參數,首先設置在多遠處開始使用組合貼圖
mTerrainGlobals->setCompositeMapDistance(100);
然後設置產生組合貼圖的光線方向
mTerrainGlobals->setLightMapDirection(Ogre::Vector3(0,-1,0));
設置組合貼圖的光影顏色
mTerrainGlobals->setCompositeMapAmbient(smgr->getAmbientLight());
mTerrainGlobals->setCompositeMapDiffuse(ColourValue::Black);
例如上麵的參數設置,就會在你的攝像機周圍100範圍內看到地形,而之外則是漸變到黑,這樣就是遊戲中隻照亮你周圍的效果
3.設置地形組
在Ogre中,地形是以組的形式出現的,一個地形組中有多個地形實例,一個組中的地形擁有相同的紋理,相同的高度圖,並很方便在他們之間平滑連接,ogre中代表地形組的類是TerrainGroup,代表一個地形實例的類是Terrain
首先我們需要new產生一個地形組
mTerrainGroup=new TerrainGroup(場景管理器直至,地形的朝向, 地形頂點數的大小, 地形麵積的大小);
Ogre手冊中關於後兩個參數說的很不通俗,經過試驗,是這樣的,第一個是頂點數目(要為2^n+1),最後一個是地形的空間尺寸(邊長)
設置地形的原點位置
mTerrainGroup->setOrigin(Ogre::Vector3::ZERO);
然後設置地形的一些具體屬性,通過Ogre::Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings()得到一個Terrain::ImportData類實例,然後修改它
defaultimp.inputScale = 600;//這是對導入數據(高度圖)的高度值的縮放,這個屬性很重要,我們知道高度圖上的高度在圖像的尺度上的範圍是0-1(0為全黑),所以默認下,地形的高度將在0-1範圍內(這基本比平原還平原),所以要使用這個值來對原始圖片上的像素值相乘,也就是這個值越大,地勢越陡峭
新版orge的地形的紋理貼附是這樣的,他允許地形上有幾個紋理層次(數目取決與你的硬件),標記位0層,1層..n層,默認情況下你隻能見到第0層,我們可以設置n+1層對之前n層紋理混合結果的混合方式,如果不混合,就隻能看到0層,首先你要定義這些層的紋理是什麼,紋理的大小
defaultimp.layerList.resize(3);//設置有幾層紋理
例如設置第0層
defaultimp.layerList[0].worldSize = 2500;//設置該層紋理的空間大小
defaultimp.layerList[0].textureNames.push_back("2.jpg");//設置該層紋理的貼圖
defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds");//設置該層紋理的法向貼圖
4。定義好每層紋理後,我們要使用地形組產生地形實例
首先導入高度圖
Ogre::Image img;
img.load("terrain.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
然後使用下麵這個函數生個一個地形實例
mTerrainGroup->defineTerrain(x, y, &img);
地形組是指一個二維網格的地形群,上麵這個函數是指在地形組這個網格的(X Y)處使用這個高度圖產生一個地形實例,在ogre中每個地形實例都是方形的,所以如果你想產生矩形地形就需要產生多個地形實例,如在(0,0)和(0,1)處產生兩個
5 在產生了地形實例後,我們需要對地形的紋理層進行我們想要的混合方式,這不就等於你在地形上鋪東西
用地形組的迭代器訪問每一個地形實例
混合的原理機製是這樣的,對於每一個紋理層,都有一個保存每個像素的alpha混合值的值,可以通過Ogre::TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(1)來獲取第1層的這個混合數據,初始情況下都是0,也就是說默認情況下第1層對第0層的混合是0,那樣你就隻能看到0層,你可以通過修改這個數據來直接修改混合方式,這就像兩張圖像做混合,而每張混合圖像代表了整個這個地形實例的表麵圖片,為了得到這個圖像的邊長,可以使用terrain->getLayerBlendMapSize(); 你還可以使用blendMap1->convertImageToTerrainSpace(x, y, &tx, &ty)來得到混合圖像空間上(x,y)的那個像素對應的地形實例空間上的坐標。
最修改了混合值之後,你需要使用
blendMap1->dirty();
blendMap1->update();
來更新
6最後我們調用mTerrainGroup->freeTemporaryResources();來做一些清理工作
當然在程序執行完畢我們需要清理掉mTerrainGroup和 mTerrainGlobals;
這就是新版Ogre的地形,雖然比之前的操作要複雜的多,我還真的琢磨了好幾天,但是可以實現非常好的地形效果,而紋理層見的混合可以製造各種紋理貼附的地形效果,大家試試看
說了地,再說天,ogre有三種表現天空的方法,skybox skydome skyplane
skybox
就是一種cube mapping
使用:
mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000, false);
其中參數1代表是否繪製
參數2代表這個cube mapping的材質
參數3代表天距離你多遠
其中參數4代表是否先繪製天空盒,如果後繪製,他將在地形的上層
skydome
這是將一個紋理圖片彎曲一下從幾個方向拚成一個天,最上麵中心可能會有拚痕
使用
mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);
這裏麵的材質就是一張普通圖片
skyplane
就簡單將一張圖片放在頭頂代表天,適用四周有群山等遮擋看不到地平線的時候
這三種越來越簡單,當然效率越來越高
mSceneMgr->setFog(Ogre::FOG_EXP, fadeColour, 0.005);
這裏麵要注意,如果你需要完全看清天空,就需要將天空的距離設置的比武的最近距離要近,否則霧會遮擋天空,盡管事實是這樣,而有時卻並非如此。
還有霧不僅可以是霧,變一變顏色,可以變成煙、黑暗或者某種恐怖的場景~
最後更新:2017-04-02 06:51:23