正面的這段代碼是在main()之后的初始化代碼:
//wrangle a pointer to the Root Ogre object
// the first param is the name of the plugins cfg file, the second is the name of the ogre cfg file
// we are not using either here, so provide them as empty strings to let Ogre know not to load them
// The third param is the name of the Ogre.log diagnostic file; leave it default for now
ogre = new Root("", "");
try {
ResourceGroupManager::getSingleton().addResourceLocation(
"resource", "FileSystem", "General");
ResourceGroupManager::getSingleton().addResourceLocation(
"resource/gui.zip", "Zip", "GUI");
VideoOptions opts;
VideoOptions::iterator it;
getOptions(opts);
std::string val;
unsigned int h, w;
bool fullscreen = false;
Ogre::RenderSystemList *renderSystems = NULL;
Ogre::RenderSystemList::iterator r_it;
val = opts.find("renderSystem")->second;
renderSystems = ogre->getAvailableRenderers();
// check through the list of available renderers, looking for the one that contains
// the string in "val" ('renderSystem' option from the config.ini file)
bool renderSystemFound = false;
for (r_it=renderSystems->begin(); r_it!=renderSystems->end(); r_it++) {
RenderSystem *tmp = *r_it;
std::string rName(tmp->getName());
// returns -1 if string not found
if ((int) rName.find(val) >= 0) {
ogre->setRenderSystem(*r_it);
renderSystemFound = true;
break;
}
}
if (!renderSystemFound) {
throw new VideoInitializationException("Specified render system (" + val + ") not found, exiting...");
}
// sscanf is the easy way to do this
val = opts.find("resolution")->second;
sscanf(val.c_str(), "%dx%d", &w, &h);
opts.erase("resolution");
val = opts.find("fullscreen")->second;
if (val == "true")
fullscreen = true;
opts.erase("fullscreen");
// false because we are not using an autocreated window
ogre->initialise(false);
window = ogre->createRenderWindow(appName, w, h, fullscreen, &opts);
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
guiSceneMgr = ogre->createSceneManager(ST_GENERIC);
showGui();
}
catch (Ogre::Exception &e) {
std::string msg = e.getFullDescription();
std::cerr << msg << std::endl;
exit (-1);
}
在這里,你不想使用默認的”對話框設置”以及不想用Ogre.cfg,而想用自己的一個文件來對所有的子系統進行配置. 因此,你需要手動地處理它.不是很大的事,你只需要對STL熟悉就行了.
ResourceGroupManager::getSingleton().addResourceLocation(
"resource", "FileSystem", "General");
ResourceGroupManager::getSingleton().addResourceLocation(
"resource/gui.zip", "Zip", "GUI");
上面的代碼,第一個目錄”resource”,在我們游戲的安裝根目錄下.在這個系列中,我們將把所有游戲的資源數據放在游戲根目錄下.加上這個目錄可以讓Ogre ResourceGroupManager知道如何去找到我們的資源. 下一語句指明Gui資源,需要注意的是,資源不能有重名,要不然會崩潰.
對Ogre的資源管理子系統需要注意的是:1.它不會到子目錄中去尋找,因此,你必須告訴它.2.文件夾的名字是沒有意義的.這就是說,如果在不同的文件夾內,有兩個文件重名的話,也是不行的.
在這里,對于我們資源的加載,首先,我們沒有導入OgreCore.zip.因為你不需要它.它對Demo是有用的.第二,我們把所有與GUI相關的內容放在了gui.zip這個文件中.
(對于CEGUI熟悉的用戶可能覺得這樣的配置不好,但是,這樣做的話,將來你在用CEGUI的配置的時候可以省掉很多麻煩).
這個章節將寫一些用于讀取config.ini的代碼.
VideoOptions 是STL std::map的typedef, getOptions() 配置讀取函數返回這個值. 巧合的是, Ogre::NameValuePairList 也是這樣用的.需要記住的是,這需要你在你的.ini配置文件中使用option名字.
在你的頭文件中,記得加入正面的typedef:
typedef NameValuePairList VideoOptions;
為了便于參考,正面是一個對于video section的配置文件:
[video]
FSAA=0
colourDepth=32
fullscreen=false
renderSystem=Direct3D9
resolution=800x600
vsync=false
這里選了一個默認的D3d渲染系統,你也可以在GUI的配置選項中,用getAvailableRenderers()來得到所有的可用的渲染API,然后選擇使用哪一個. 一旦你有了渲染系統,你就可以創建主要的Ogre window.
getOptions()是一個簡單的函數,其使用Win32的SHGetFolderPath() API或Linux中的$HOME變量和Win32
GetPrivateProfileSection()來讀配置文件的sections.這些讀出的內容放在VideoOptions表里面.下面是getOptions()的代碼:
#ifdef WIN32
#include <shlobj.h>
#else
#endif
bool getOptions(VideoOptions opts)
{
// read these from the ubiquitous config file...on Win32 we have a nice handy
// API to read config files; on other platforms we'll need to fake one
char path[MAX_PATH+1];
#ifdef WIN32
SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path);
#else
#endif
std::string pathname(path);
pathname += "/" + CONFIG_OPTS_DIR + "/" + CONFIG_FILE_NAME;
#ifdef WIN32
DWORD nSize = 1024, rtnSize;
char strVal[1024], *cp = strVal;
// yes I know this is not the right way to handle this situation...sue me. :p
rtnSize = GetPrivateProfileSection("video", strVal, nSize, pathname.c_str());
if (rtnSize == nSize - 2)
throw new VideoInitializationException("Cannot read video settings - buffer too small");
if (rtnSize == 0)
return false;
std::string name, val;
opts.clear();
while (*cp != 0 && *(cp+1) != 0) {
name = cp;
val = cp;
cp += strlen(cp) + 1;
name = name.substr(0, name.find('='));
val = val.substr(val.find('=') + 1);
opts.insert(VideoOptions::value_type(name, val));
}
#else
#endif
return true;
}
在Win32環境中需要添加頭文件"shlobj.h".
CONFIG_OPTS_DIR 是你的配置文件夾的位置. CONFIG_FILE_NAME 在我們這個例子中是 "config.ini"; 在后面會看到,如果用戶沒有config.ini,我們會創建一個合適的默認給它.現在我們用Lua腳本讀出它的配置信息