flagship的理想与现实

创新+实践

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  8 Posts :: 0 Stories :: 27 Comments :: 0 Trackbacks

常用链接

留言簿(8)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

        资源异步加载恐怕是3D引擎中应用最为广泛的多线程技术了,特别是在无缝地图的网络游戏中,尤为重要,公司3D引擎的资源加载部分采用了硬盘->内存->显存两级加载的模式,超时卸载也分两级,这样虽然实际效果不错,但代码非常繁琐,在FlagshipEngine中,我设法将其进行了一定程度的简化。

首先我们需要定义一个Resource基类,它大致上是这样的:
class _DLL_Export Resource : public Base
    
{
    
public:
        Resource();
        
virtual ~Resource();

        
// 是否过期
        bool                IsOutOfDate();
       

    
public:
        
// 是否就绪
        virtual bool    IsReady();

        
// 读取资源
        virtual bool    Load();

        
// 释放资源
        virtual bool    Release();

        
// 缓存资源
        virtual bool    Cache();

        
// 释放缓存
        virtual void    UnCache();

    
protected:
        
// 加载标记
        bool            m_bLoad;

        
// 完成标记 
        bool            m_bReady;
        

    
private:

    }
;
        在实际游戏中,加载资源的范围大于视野,当摄像机移动到单元格边缘(必须有一定的缓冲区),就应将新的单元格中的对象加入到资源加载队列中,唤醒资源加载线程调用Load接口进行加载,完成后将该资源的加载标记设为true。而通过可视剪裁所得到的最终可视实体,则需要调用Cache接口构建图像API所需对象,当Load和Cache都完成后IsReady才会返回true,这时该资源才能开始被渲染。
        卸载方面,在加载新的单元同时,卸载身后旧的单元,对单元内所有资源调用Release,Load/Release带有引用计数,仍被引用的资源不会被卸载。当某一资源长时间没有被看见,则超时,调用UnCache释放VertexBuffer等资源。
        为了实现超时卸载功能,我们需要一个ResourceManager类,每帧检查几个已Cache的资源,看起是否超时,另外也需对已加载的资源进行分类管理,注册其资源别名(可以为其文件名),提供查找资源的接口。
        另外为了方便使用,我们需要一个模板句柄类ResHandle<T>,设置该资源的别名,其内部调用ResourceManange的查找方法,看此资源是否已存在,如不存在则new一个新的,GetImpliment则返回该资源对象,之后可以将该资源添加到实体中,而无需关心其是否已被加载,代码如下:
template <class T>
    
class _DLL_Export ResHandle
    
{
    
public:
        ResHandle() 
{ m_pResource = NULL; }
        
virtual ~ResHandle() {}

        
// 设置资源路径
        void            SetPath( wstring szPath )
        
{
            Resource 
* pResource = ResourceManager::GetSingleton()->GetResource( Key( szPath ) );
            
if ( pResource != NULL )
            
{
                m_pResource 
= (T *) pResource;
            }

            
else
            
{
                m_pResource 
= new T;
                m_pResource
->SetPath( szPath );
                ResourceManager::GetSingleton()
->AddResource( m_pResource );
            }

        }


        
// 模板实体类指针
        T *             GetImpliment() return (T *) m_pResource; }

        T 
*             operator-> () return (T *) m_pResource; }

    
protected:
        
// 模板实体类指针
        Resource *      m_pResource;

    
private:
    }
;

posted on 2009-01-03 21:37 flagship 阅读(3510) 评论(0)  编辑 收藏 引用 所属分类: FlagshipEngine

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理