第十回 资源管理
移动时,同一个目录下的文件一般是一起移动的,这样就不会出现路径名失效的问题.这种情况在开发中还是比较常见的 3.提高程序的健壮性,在引用的资源读取失败后,绝对不能当机,并要能输出错误信息 4.在编辑器中提供方便的修补功能,如下图:
首先我们对于missing的资源名用醒目的颜色标识出来,然后我们提供修补按钮,自动在整个目录里搜索,找出最匹配的路径名供用户选择. 上面提到了资源数据的载入,由于采用了多线程载入,这个过程变得复杂了,资源对象分为多个状态: enum ResourceState { Empty=0, Loading, Loaded, Failed, Ready, }; 资源对象的载入过程包括以下几步: 1.资源管理器创建一个资源对象,此时它的状态为Empty 2.资源管理器将这个资源对象连同它的路径名加入到一个文件载入线程中,并标记资源的状态为Loading. 3.资源管理器将资源对象加到资源对象列表中,并将资源对象的指针返回 4.文件载入线程根据文件名将资源文件的原始数据全部读到内存里来,把这块内存保存到资源对象内部,并把资源对象的状态标记为Loaded,如果文件载入失败,就标记为Failed 5.任何资源在每次使用前都要调用Touch(),Touch()的返回值有三中:Ok,Fail和Waiting 6.Touch()函数内部会检查对象的当前状态, 如果为Failed,则返回Fail, 如果为Loading则返回Waiting, 如果为Loaded,则会根据从文件里读出的原始数据创建真正的资源对象数据.如果成功,则把资源状态标记为Ready,并返回Ok,否则标记为Failed,并返回Fail. 如果已经是Ready了,则返回Ok, 7.资源的使用者根据Touch()的返回值来决定要不要使用这个资源,如果返回值为Waiting,它可以选择暂时不使用这个资源(比如界面上显示的某张图片尚未载入时,我们可以暂时不画它),
也可以等待资源被载入: while(pRes->Touch()==Waiting); //这也是ForceTouch()所做的事情. 目前引擎中的资源管理还是比较简陋的,只是完成了一些基本的功能.需要改进的地方有: 1. 对于贴图资源,也许要考虑能够先快速的载入一张低精度的版本用于显示,然后在后台继续载入高精度版本 2. 对于角色动画资源等数据量比较大的资源,也许要考虑只读取资源某一部分的情况. 我能想到的就这些,如果谁有好的建议,也欢迎提出来,一起讨论. 不过我觉得要保证游戏在载入时没有明显的延迟,归根结底还是上层要能够提供一套好的载入预测机制,这不是资源管理器可以解决的. 最后说一下资源热加载的功能,所谓资源热加载,就是在不需要重启游戏或者编辑器的情况下,对资源文件的修改可以立即反映到游戏中去.比如游戏里的一个角色使用某张贴图,我们可以边在PhotoShop里修改这张贴图,边在游戏里看到实际修改的效果,而不用退出游戏.我们在实现了shader的热加载以后,shader的调试时间被大大缩短了,某种程度上比调试vc程序更方便.游戏编程精粹第六册里详细介绍了这种技术,我们也是重点参考了它的源代码.我觉得这是个性价比很高的功能,一旦实现了它,你一定会后悔没有更早实现它的. 资源管理就说到这,下回说说shader.