OGRE除了我們已經見過的普通場景以外還支持大型複雜的場景,如:寬闊的野外地形和複雜的大樓和迷宮。3D引擎支持大型複雜場景的主要難度在於對場景的組織和裁減。一個大型場景的三角型數量極其龐大,如果沒有有效的場景組織和裁減方法,計算機在渲染的時候效率會很低。解決大辦法就是用BSP或八叉樹等數據結構將場景組織起來,利用與這些數據結構相關的快速檢索算法將攝象機看到的內容揀選出來,再送到渲染器進行渲染,這樣圖形處理器的負載纔會減小。
在OGRE中場景管理器的類型有四種:
ST_GENERIC, 普通場景
ST_EXTERIOR_CLOSE, 室外封閉場景
ST_EXTERIOR_FAR, 室外無限場景
ST_INTERIOR 室內場景
除了第一種普通場景外,其它幾種都是處理複雜場景的專用場景管理器。OGRE引擎中有一個SceneManagerEnumerator類,它的作用是管理已實現的場景管理器。在OGRE的Root類裏就就聚合了一個SceneManagerEnumerator對象,已供選擇需要的場景管理器。在OGRE FrameWork的ExampleApplication類中可以看到這樣的代碼:
從以上代碼可知,在普通情況下使用的是普通場景管理器。如果要使用特殊的場景管理器,通過mRoot->getSceneManager()函數做出選擇就可以了。
在OGRE的SceneManager類中有這樣的一個函數setWorldGeometry,它的作用是讀入世界信息(複雜場景中的大樓、野外地形等不變場景內容,區別於程序員手工加入的可以控制的場景元素),並將其管理起來。對於普通場景管理器來講,沒有“World Surface(Terrain,Room...)”這個概念,調用這個函數將只會拋出一個 "World geometry is not supported by the generic SceneManager." 的異常。
而OGRE在其引擎提供的Plugin_BSPSceneManager.dll中提供了通過BSP算法實現的ST_INTERIOR 室內場景管理器,它重新實現了setWorldGeometry函數,使其可以讀入一個.bsp的室內場景文件並管理之。.bsp是QUAKE和CS等室內遊戲使用的場景文件類型。OGRE還在其引擎提供的Plugin_OctreeSceneManager.dll中提供了通過八叉樹算法實現的ST_EXTERIOR_CLOSE室外封閉場景管理器,它同樣重新實現了setWorldGeometry函數,使其可以讀入一個.cfg室外場景配置文件,並載入以灰度圖形式表達的地形高程圖。
需要注意的是特殊場景管理器不僅可以管理複雜場景中那些屬於“World Surface”(複雜場景中的大樓、野外地形等不變場景內容)的場景內容,它也具有普通場景管理器的全部功能。所以在應用時,通過setWorldGeometry函數載入“不變世界”之後依然可以向場景中加入SceneNode和Entity等其它場景元素,依然可以通過FrameLisener來控制這些普通場景元素的運動。只不過它們將在一個具有樓房或山坡的場景中運動了。
室內場景
Demo_BSP工程是OGRE引擎帶的室內場景例子。打開Demo_BSP工程查看代碼。
OGRE在其引擎提供的Plugin_BSPSceneManager.dll插件中提供了通過BSP算法實現的ST_INTERIOR室內場景管理器。OGRE引擎在初始化的時候會載入Plugins.cfg中指定的全部插件,只要在Plugins.cfg中包含Plugin_BSPSceneManager.dll插件就可以使用了。
由於OGRE目前支持的是QUAKE3的地圖,所以必須有一個quake3settings.cfg來指定QUAKE3的地圖包(. pk3文件,其實是一個ZIP文件)和其中的地圖文件名(.bsp)。QUAKE3是一個商業遊戲軟件,其中的全部地圖的知識產權都屬於ID公司,所以OGRE引擎的DEMO程序並沒有附帶任何QUAKE3地圖,你必須在自己的計算機上安裝QUAKE3的地圖包,並將路徑設置到quake3settings.cfg中去,Demo_BSP才能夠正確運行。
在BSP.h文件中,定義了BspApplication類,該類的構造函數首先讀入quake3settings.cfg,並解析出其中的地圖包文件名和地圖文件名。代碼如下:
地圖包文件實際上是一個ZIP文件,該ZIP文件中包含OGRE真正需要的實際擴展名爲.bsp的地圖文件,所以還必須將地圖包ZIP文件加入到OGRE的資源搜索路徑中去。代碼如下:
由於採用了特殊的室內場景管理器,所以必須重新實現chooseSceneManager函數,以選擇正確的場景管理器。代碼如下:
最後是創建場景,代碼如下:
在創建場景的過程中,首先通過場景管理器的setWorldGeometry方法載入地圖。
接下來是設置攝象機。QUAKE地圖中都有預先設置好的起始點和起始方向,通過場景管理器的getSuggestedViewpoint方法可以獲取到這個ViewPoint,而後再將攝象機定位到這個點上。由於QUAKE是以XY軸構成的平面爲水平面,Z軸爲上方向,所以必須將攝象機用mCamera->pitch(90)語句調整90度。mCamera->rotate(vp.orientation);一句的意思是將攝象機調整到起始方向。最後將攝象機的旋轉軸固定,因爲人只能頭向上走路,不能象飛機那樣360度全空間翻滾。因爲在QUAKE中Z軸向上,所以通過mCamera->setFixedYawAxis(true, Vector3::UNIT_Z);語句實現。
室外場景
Demo_Terrain工程是OGRE自帶的室外場景的例子,打開該工程查看代碼。
OGRE在其引擎提供的Plugin_OctreeSceneManager.dll插件中提供了通過八叉樹算法實現的ST_EXTERIOR_CLOSE室外封閉場景管理器。OGRE引擎在初始化的時候會載入Plugins.cfg中指定的全部插件,只要在Plugins.cfg中包含Plugin_OctreeSceneManager.dll插件就可以使用了。
室外場景的主要內容是起伏的地形。表現地形起伏的一般方法是通過一個灰度圖來表達場景中每一塊土地的高度,顏色淺爲高,顏色深爲低。引擎讀取這個灰度圖,並根據每個像素的顏色值畫出高低起伏的地形網格。再用另外的彩色圖作爲地表紋理鋪在地形網格上,就實現了室外場景。
除此之外,爲了防止地表紋理放大造成的失真,還需要一個代表地面細節的可拼接的細節紋理圖。地形顯示的時候應該還可以設置縮放因子。OGRE將這些地形顯示需要的圖片和屬性都放在terrain.cfg文件中設置。請查看terrain.cfg。
在程序中實現室外場景漫遊很簡單。首先需要選擇室外場景管理器,代碼如下:
選擇好室外場景管理器後,通過該場景管理器創建場景就可以了。
以上的createScene函數首先設置環境光,又創建了一個點光源。通過mSceneMgr -> setWorldGeometry( "terrain.cfg" );語句載入terrain.cfg配置文件,解析它,同時創建地形。場景管理器的setFog函數可以設置霧化效果。
儘管本例使用的是室外場景管理器,我們依然可以用熟悉的方法向場景中加入Entity等場景元素,試着向程序中加入如下代碼並查看效果。
這部分代碼向場景中加入了一個食人魔。從這裏可以看到,場景管理器的setWorldGeometry方法會將固定不變的地形創建好,我們還可以很方便的向場景中加入其它可運動的物體(汽車、動物等),從而實現一個近乎真實的野外世界。