flagship的理想与现实

创新+实践

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

常用链接

留言簿(8)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

        在实际游戏中,逻辑线程需要对渲染对象做许多操作,比如添加与删除,改变渲染对象的属性等等,而由于在先前的设计中,逻辑线程与渲染线程相互独立,如果只是改变某一共享数据,没有问题,但如果操作影响到了场景结构,例如实体的添加与删除,则必须进行线程同步,这又违背了FlagshipEngine的设计初衷——避免繁重的逻辑计算影响渲染速度。
        解决办法其实在上一篇中已经提到了,仍然是利用天然的同步机制——Windows消息,添加实体时,逻辑线程只是new了一个Entity对象,设置这个对象的初始共享数据,比如位置信息,同时向渲染线程发送一条WM_ADDENTITY的自定义消息,将Entity指针作为wParam传递。渲染线程接受到消息后调用Entity的UpdateScene方法,更新Entity在场景树中的位置,并加载资源。
        删除也是一样,逻辑线程向渲染线程发送WM_DELETEENTITY消息,并不再使用该Entity指针,渲染对象则处理改消息,将此Entity从场景中删除并卸载资源。
        这里有一个非常危险的情况,前面一篇提到,资源加载也是通过消息传递实现的,同样是传递的资源指针,如果逻辑线程添加了一个Entity,还没加载就删掉了它,则资源加载线程会拿到一个过期指针,一切就结束了。。。
        解决这一问题,最稳妥的方法是消息的wParam并不传递指针,而是传递该Entity或资源的唯一ID,这样的话即使ID过期,也可轻松忽略掉这条消息,坏处是每次消息处理都的从全局的map里检查是否存在此ID对应的Entity或资源,这可是笔不小的开销。
        第二种方案,我们仍然传递指针,只是在接受到WM_DELETEENTITY消息时,检查该Entity是否已经加载完成,如果没有完成,则重新将此消息加入消息队列,下个渲染帧再次判断。
       FlagshipEngine的多线程设计大致就是如此了。
posted on 2009-01-24 23:38 flagship 阅读(1809) 评论(1)  编辑 收藏 引用 所属分类: FlagshipEngine

Feedback

# re: 3D引擎多线程:逻辑操作 2009-03-15 00:51 seesea
关注中...  回复  更多评论
  


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