正面的这段代码是在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脚本读出它的配置信息