出處:http://blog.csdn.net/leonwei/archive/2010/07/26/5767350.aspx
地形
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
就簡單將一張圖片放在頭頂代表天,適用四周有群山等遮擋看不到地平線的時候
這三種越來越簡單,當然效率越來越高
霧
ogre中霧的使用很簡單,你需要在被霧影響的物體繪製前調用霧的繪製:
mSceneMgr->setFog(Ogre::FOG_EXP, fadeColour, 0.005);
這裡面第一個參數是霧計算的數學模型,有線性和指數型
第二個是霧的顏色,注意你需要將視口的背景顏色也設定成此顏色
後面是一些在具體數學模型下的參數
這裡面要注意,如果你需要完全看清天空,就需要將天空的距離設定的比武的最近距離要近,否則霧會遮擋天空,儘管事實是這樣,而有時卻並非如此。
還有霧不僅可以是霧,變一變顏色,可以變成煙、黑暗或者某種恐怖的情境~