Ogre材质解析代码初步分析(一)

来源:互联网 发布:娄底网络电视台 编辑:程序博客网 时间:2024/05/16 15:39

本文参考:http://www.cnblogs.com/yzwalkman/archive/2012/12/30/2839013.html 尊重原创


Ogre总体资源加载

以“.material”、“.program”、“.particle”和“.compositor”为后缀的文件都统一由ScriptCompilerManager类型对象统一进行管理和解析。ScriptCompilerManager自身也是以ScriptLoader为基类的,Oger在初始化Root对象时,会创建一个ScriptCompilerManager对象,并通过ResourceGroupManager::_registerScriptLoader()函数,将它的指针保存到ResourceGroupManager的mScriptLoaderOrderMap容器中,ResourceGroupManager的mScriptLoaderOrderMap中保存的第一个ScriptLoader对象,实际上就是ScriptCompilerManager的对象指针。

ResourceGroupManager::initialiseResourceGroup()会调用ResourceGroupManager::parseResourceGroupScripts()函数,对相应ResourceGroup中的脚本文件进行解析。

parseResourceGroupScripts()代码及注释:

void ResourceGroupManager::parseResourceGroupScripts(ResourceGroup* grp){//记录解析资源组脚本日志LogManager::getSingleton().logMessage("Parsing scripts for resource group " + grp->name);//统计需要解析的脚本数量        typedef list<FileInfoListPtr>::type FileListList;        typedef SharedPtr<FileListList> FileListListPtr;        typedef std::pair<ScriptLoader*, FileListListPtr> LoaderFileListPair;        typedef list<LoaderFileListPair>::type ScriptLoaderFileList;        ScriptLoaderFileList scriptLoaderFileList;size_t scriptCount = 0;// 遍历所有用户脚本,并且获得数据流ScriptLoaderOrderMap::iterator oi;for (oi = mScriptLoaderOrderMap.begin();oi != mScriptLoaderOrderMap.end(); ++oi){ScriptLoader* su = oi->second;// MEMCATEGORY_GENERAL 是唯一支持 SharedPtr 的内存类型        FileListListPtr fileListList(OGRE_NEW_T(FileListList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T);// 搜寻并获得所有需要解析的类型(“.material”、“.program”、“.particle”、“.compositor”)const StringVector& patterns = su->getScriptPatterns();for (StringVector::const_iterator p = patterns.begin(); p != patterns.end(); ++p){FileInfoListPtr fileList = findResourceFileInfo(grp->name, *p);scriptCount += fileList->size();fileListList->push_back(fileList);}         scriptLoaderFileList.push_back(                LoaderFileListPair(su, fileListList));}//触发解析脚本事件fireResourceGroupScriptingStarted(grp->name, scriptCount);//遍历脚本并且解析// Note we respect original ordering        for (ScriptLoaderFileList::iterator slfli = scriptLoaderFileList.begin();            slfli != scriptLoaderFileList.end(); ++slfli)        {ScriptLoader* su = slfli->first;        //遍历每一个链表        for (FileListList::iterator flli = slfli->second->begin(); flli != slfli->second->end(); ++flli)        {for (FileInfoList::iterator fii = (*flli)->begin(); fii != (*flli)->end(); ++fii){bool skipScript = false;                   fireScriptStarted(fii->filename, skipScript);if(skipScript){LogManager::getSingleton().logMessage("Skipping script " + fii->filename);}else{LogManager::getSingleton().logMessage("Parsing script " + fii->filename);                        DataStreamPtr stream = fii->archive->open(fii->filename);                        if (!stream.isNull())                        {if (mLoadingListener)mLoadingListener->resourceStreamOpened(fii->filename, grp->name, 0, stream);if(fii->archive->getType() == "FileSystem" && stream->size() <= 1024 * 1024){DataStreamPtr cachedCopy;cachedCopy.bind(OGRE_NEW MemoryDataStream(stream->getName(), stream));su->parseScript(cachedCopy, grp->name);}else                            su->parseScript(stream, grp->name);                        }                   }fireScriptEnded(fii->filename, skipScript);}            }}fireResourceGroupScriptingEnded(grp->name);LogManager::getSingleton().logMessage("Finished parsing scripts for resource group " + grp->name);}

以上主要是根据资源组里面的路径,遍历并且加载后缀名匹配的脚本文件到内存流中来(DataStreamPtr stream = fii->archive->open(fii->filename);
)。然后解析脚本su->parseScript(*, *);

su->parseScript(*, *);代码如下:

void ScriptCompilerManager::parseScript(DataStreamPtr& stream, const String& groupName){#if OGRE_THREAD_SUPPORT// check we have an instance for this thread (should always have one for main thread)if (!OGRE_THREAD_POINTER_GET(mScriptCompiler)){// create a new instance for this thread - will get deleted when// the thread diesOGRE_THREAD_POINTER_SET(mScriptCompiler, OGRE_NEW ScriptCompiler());}#endif// Set the listener on the compiler before we continue{OGRE_LOCK_AUTO_MUTEXOGRE_THREAD_POINTER_GET(mScriptCompiler)->setListener(mListener);}        OGRE_THREAD_POINTER_GET(mScriptCompiler)->compile(stream->getAsString(), stream->getName(), groupName);}
stream->getAsString()用来将脚本文件中的内容以字符串的形式加载到内存;stream->getName()用来返回待解析脚本文件的文件名。


以上就是基本的资源组里面加载脚本文件的基本过程,下面几篇详细描述解析过程。



0 0
原创粉丝点击