ogre 引擎 框架追踪 第三章 资源加载之虚加载
来源:互联网 发布:淘宝库房分拣员累吗 编辑:程序博客网 时间:2024/06/05 19:38
前序 ogre 引擎 框架追踪 第二章 初始化
前面两章已经创建root、加载dll、创建渲染系统、创建渲染窗口。这章,我们该往整个框架里塞东西了。ogre1.8用的单线程,不支持后台加载。关于资源的操作就是:
创建资源管理器->继承不同资源管理器的创建->向资源管理器添加路径->初始化已添加路径的资源->加载资源->渲染资源。
前面两步已经在前面实现,接下来的开始添加路径。
1、ogre资源的路径添加
ogre中有两种方式实现路径加载,一种傻瓜式加载,直接传入一个cfg文件名称,解析了就把解析的资源目录添加到资源管理器中,另一种就是手动添加,直接调用资源管理器向里面添加资源。
resouce.cfg
第一种,傻瓜式的。
先看下resouce.cfg里的内容
[Essential] #资源分组名称,这个里面是ogre自带的最基础的资源#这里有traymanager里所需的资源,包括overlay、鼠标、字体Zip=../../media/packs/SdkTrays.zip Zip=../../media/packs/profiler.zip FileSystem=../../media/thumbnails # Common sample resources needed by many of the samples.# Rarely used resources should be separately loaded by the# samples which require them.[Popular]FileSystem=../../media/fontsFileSystem=../../media/materials/programsFileSystem=../../media/materials/scriptsFileSystem=../../media/materials/texturesFileSystem=../../media/materials/textures/nvidiaFileSystem=../../media/modelsFileSystem=../../media/particleFileSystem=../../media/DeferredShadingMediaFileSystem=../../media/PCZAppMediaFileSystem=../../media/RTShaderLibFileSystem=../../media/RTShaderLib/materialsFileSystem=../../media/materials/scripts/SSAOFileSystem=../../media/materials/textures/SSAOZip=../../media/packs/cubemap.zipZip=../../media/packs/cubemapsJS.zipZip=../../media/packs/dragon.zipZip=../../media/packs/fresneldemo.zipZip=../../media/packs/ogretestmap.zipZip=../../media/packs/ogredance.zipZip=../../media/packs/Sinbad.zipZip=../../media/packs/skybox.zip[General]FileSystem=../../media# Materials for visual tests[Tests]FileSystem=../../media/../../Tests/Media[Popular] Zip=../../media/packs/NxOgre.zip
结构上就是:
[分组组名]
Zip=**.zip #zip文件目录
FileSystem=** #文件夹
解析并加载cfg文件
void RenderScene::setupResources(Ogre::String cfgFile){ ConfigFile cf; cf.load(cfgFile);//加载并解析 // Go through all sections & settings in the file ConfigFile::SectionIterator seci = cf.getSectionIterator(); String secName, typeName, archName; while (seci.hasMoreElements()) { secName = seci.peekNextKey(); ConfigFile::SettingsMultiMap *settings = seci.getNext(); ConfigFile::SettingsMultiMap::iterator i; for (i = settings->begin(); i != settings->end(); ++i) { typeName = i->first; archName = i->second; //资源管理器中添加资源路径 ResourceGroupManager::getSingleton().addResourceLocation( archName, typeName, secName); } }}
.cfg文件的解析,最终的实现:
std::ifstream fp; // Always open in binary mode fp.open(filename.c_str(), std::ios::in | std::ios::binary); if(!fp) OGRE_EXCEPT( Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!", "ConfigFile::load" ); // Wrap as a stream,转换成ogredatastream,代码不难,就是用windows的方法获取大小,再用模板类转换成datasteam,可以自己看。 DataStreamPtr stream(OGRE_NEW FileStreamDataStream(filename, &fp, false)); load(stream, separators, trimWhitespace);//继续,根儿上的解析
根儿上的解析
void ConfigFile::load(const DataStreamPtr& stream, const String& separators, bool trimWhitespace) { clear();//清理之前加载的东西 String currentSection = StringUtil::BLANK; SettingsMultiMap* currentSettings = OGRE_NEW_T(SettingsMultiMap, MEMCATEGORY_GENERAL)();//用ogre_new智能指针新建,不用担心释放了就 mSettings[currentSection] = currentSettings; /* Process the file line for line */ String line, optName, optVal; while (!stream->eof()) { line = stream->getLine();//读取一行并返回 /* Ignore comments & blanks,不管#开头的(注释)和@开头的 */ if (line.length() > 0 && line.at(0) != '#' && line.at(0) != '@') { if (line.at(0) == '[' && line.at(line.length()-1) == ']')//读取"[]"内的为组名 { // Section currentSection = line.substr(1, line.length() - 2); SettingsBySection::const_iterator seci = mSettings.find(currentSection); if (seci == mSettings.end()) { currentSettings = OGRE_NEW_T(SettingsMultiMap, MEMCATEGORY_GENERAL)(); mSettings[currentSection] = currentSettings; } else { currentSettings = seci->second; } } else//不是组名的添加到当前组中 { Ogre::String::size_type separator_pos = line.find_first_of(separators, 0); if (separator_pos != Ogre::String::npos) { optName = line.substr(0, separator_pos);//等号前的name Ogre::String::size_type nonseparator_pos = line.find_first_not_of(separators, separator_pos); optVal = (nonseparator_pos == Ogre::String::npos) ? "" : line.substr(nonseparator_pos);//等号后的value if (trimWhitespace) { StringUtil::trim(optVal); StringUtil::trim(optName); } currentSettings->insert(SettingsMultiMap::value_type(optName, optVal));//当前组中添加name和value } } } } }
添加到资源管理器
解析出的信息通过addResourceLocation添加到资源管理器中,添加过程:
获取resoucegroup->有则获取无则创建->文件管理器加载
//获取group ResourceGroup* grp = getResourceGroup(resGroup); if (!grp) { createResourceGroup(resGroup); grp = getResourceGroup(resGroup); } //锁资源分组 OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME) // lock group mutex // Get archive Archive* pArch = ArchiveManager::getSingleton().load( name, locType ); // Add to location list ResourceLocation* loc = OGRE_NEW_T(ResourceLocation, MEMCATEGORY_RESOURCE); loc->archive = pArch; loc->recursive = recursive; grp->locationList.push_back(loc); // Index resources StringVectorPtr vec = pArch->find("*", recursive);//获取文件路径中所有文件 for( StringVector::iterator it = vec->begin(); it != vec->end(); ++it ) grp->addToIndex(*it, pArch);//通过文件名保存archive。已判断资源存在不存在、文件对象是啥等等。
先解析ArchiveManager::getSingleton().load这个函数,实现由注册的文件工厂(文件类型)根据文件路径创建文件并加载
其中核心代码:
ArchiveFactoryMap::iterator it = mArchFactories.find(archiveType);//前面root创建时我们已经注册过FileSystemArchiveFactory、ZipArchiveFactory、EmbeddedZipArchiveFactory if (it == mArchFactories.end()) 。。。 //没找到就报错。 pArch = it->second->createInstance(filename);//创建文件对象 pArch->load(); //加载 mArchives[filename] = pArch;
其中FileSystemArchive的load代码如下
OGRE_LOCK_AUTO_MUTEX String testPath = concatenate_path(mName, "__testwrite.ogre"); std::ofstream writeStream; writeStream.open(testPath.c_str()); if (writeStream.fail()) mReadOnly = true; else { mReadOnly = false; writeStream.close(); ::remove(testPath.c_str()); }
我的妈呀,发现里面就是虚晃一枪,就是检查了下路径存在不存在,是不是只读,别的啥也没干啊
再看下ZipArchive的load
OGRE_LOCK_AUTO_MUTEX if (!mZzipDir) { zzip_error_t zzipError; mZzipDir = zzip_dir_open_ext_io(mName.c_str(), &zzipError, 0, mPluginIo);//打开 checkZzipError(zzipError, "opening archive"); // Cache names ZZIP_DIRENT zzipEntry; while (zzip_dir_read(mZzipDir, &zzipEntry))//读取 { FileInfo info; info.archive = this; // Get basename / path StringUtil::splitFilename(zzipEntry.d_name, info.basename, info.path); info.filename = zzipEntry.d_name; // Get sizes info.compressedSize = static_cast<size_t>(zzipEntry.d_csize); info.uncompressedSize = static_cast<size_t>(zzipEntry.st_size); // folder entries if (info.basename.empty()) { info.filename = info.filename.substr (0, info.filename.length () - 1); StringUtil::splitFilename(info.filename, info.basename, info.path); info.compressedSize = size_t (-1); } mFileList.push_back(info);//添加zip中的内容到zip archive的文件列表中 } }
zip的倒是干了点事儿,那就是读取zip中文件列表并保存,以备后期真正的加载。
在虚加载之后,就是把路径中所有文件及对应的archive对象保存,以备后面使用。
简单描述虚加载就是:读取文件路径、zip,添加到各自的group,并且保存里面的文件与archive对象的对应。
虚加载之后,就是资源的初始化,下一章开始。
- ogre 引擎 框架追踪 第三章 资源加载之虚加载
- ogre 引擎 框架追踪 第五章 资源加载之实加载
- ogre 引擎 框架追踪 第四章 资源加载之资源组初始化
- ogre 引擎 框架追踪 第七章 渲染流程之compositor
- OGRE加载资源文件框架
- ogre 引擎 框架追踪 第二章 初始化
- ogre 引擎 框架追踪 第六章 渲染流程
- Ogre的资源加载策略
- Ogre资源加载流程概述
- ogre 引擎 框架追踪 第一章 root的创建
- libgdx游戏引擎(六)之资源异步加载
- unity 资源加载框架设计
- unity 资源加载框架设计
- iOS开发APP瘦身之PDF图片资源加载框架
- 3D引擎多线程:资源异步加载
- 3D引擎多线程:资源异步加载
- 第六章 OGRE中场景管理器、资源加载、manualObject的使用
- 在Ogre中加载自己的资源包
- laravel excel 导入
- 【淘淘】拦截器原理、实现
- 截屏应注意的细节和尝试(导出的图片一片黑色)
- OpenStack 镜像服务Glance [三]
- Ugly Number II
- ogre 引擎 框架追踪 第三章 资源加载之虚加载
- JAVA——第四章——类与对象
- webstorm 主题 配色
- 第1章 BashShell命令------------(默认的shell环境变量与path变量的设置)
- OpenStack 计算服务Nova [四]
- SharePoint Framework系列(七)-构建第一个webpart(连接到SharePoint)
- 注册控件失败之一:提示0x80040200错误的处理办法
- PE总结 – 资源表
- 167. Two Sum II - Input array is sorted