随笔 - 5, 文章 - 0, 评论 - 24, 引用 - 0
数据加载中……

Ogre在游戏开发中逐帧更新

最新的Ogre稳定版本是1.6.0RC1[shoggoth],在1.6.0版本中OgreFrameListener.h中的类FrameListener多出了一个叫virtual bool frameRenderingQueued( const FrameEvent& evt ) { return true; }的函数。这个函数和virtual bool frameStarted( const FrameEvent& evt ) { return true; }有明显的区别。
在源代码中对frameStarted的注释是:
        /** Called when a frame is about to begin rendering.
  @remarks
   This event happens before any render targets have begun updating.
            @return
                True to go ahead, false to abort rendering and drop
                out of the rendering loop.
        */
大体翻译是:
当一帧将要开始渲染的时候被调用。
这个事件发生在所有渲染目标已经开始更新之前。
而在源代码中对frameRenderingQueued的注释是:
  /** Called after all render targets have had their rendering commands
   issued, but before render windows have been asked to flip their
   buffers over.
  @remarks
   The usefulness of this event comes from the fact that rendering
   commands are queued for the GPU to process. These can take a little
   while to finish, and so while that is happening the CPU can be doing
   useful things. Once the request to 'flip buffers' happens, the thread
   requesting it will block until the GPU is ready, which can waste CPU
   cycles. Therefore, it is often a good idea to use this callback to
   perform per-frame processing. Of course because the frame's rendering
   commands have already been issued, any changes you make will only
   take effect from the next frame, but in most cases that's not noticeable.
  @return
   True to continue rendering, false to drop out of the rendering loop.
  */
翻译为:
在所有渲染目标已经传出他们的渲染命令之后,并且在渲染窗口被要求去释放他们的帧之前。
这个事件的用途其实是为了把GPU处理的渲染命令推入队列,这些只花费一点功夫去完成,
而就这一段时间cpu可以被用来处理一些有用的事情。一旦释放帧这个时间发生,这条线程请求将要被
堵塞直到GPU准备好了,这可能浪费了cpu的渲染时间,然而,作为回调函数去逐帧处理也是一个好注意。
当然因为帧的渲染命令已经被放出,任何你做的改变只对下一帧有效,但是大多数情况下这不是很明显的。

加入了这个函数也说明了Ogre1.6.0对gpu重视了。
在ogre自带的例子中,几乎都是用examplelistener来处理游戏循环。这明显不符合比较大点的游戏开发。而如果
你想要在大型游戏中应用这个游戏循环。我感觉首先应该有一个单件的帧监听系统通过游戏主应用程序来初始化。然后就是用设计模式中的Bridge的将声明和执行分开的功能来处理这个方法。
伪代码:

//一个部件的类
class BrilyfWidgets
{
    
bool frameRenderingQueued( const FrameEvent& evt ); 
    
}
;


//类的前向声明
class BrilyfApplication;

class BrilyfListenSystem : public Singleton<BrilyfListenSystem>public FrameListener
{
    
bool frameRenderingQueued( const FrameEvent& evt ) 
    
{
        
//一些系统缺省的设置
        
        
//关键部分
        BrilyfApplication::getSingletonPtr()->frameRenderQueued( const FrameEvent& evt );
        BrilyfApplication::getSingletonPtr()
->frameEnded( const FrameEvent& evt );
    }

    
bool frameEnded( const FrameEvent& evt );    
}
;

//所有的其他一些部件的初始化都要通过BrilyfApplication,它就是游戏的主管道,控制着所有部件的生命周期,提供了
//frameRenderingQueued和frameEnded的接口供其他的部件来填充。
class BrilyfApplication : public Singleton<BrilyfApplication>
{
    
//一些对于单件初始化的处理
    
    
    
//对应的事件
    bool frameRenderingQueued( const FrameEvent& evt ) 
    

        
for ( int i = 0; i < 16; i++ )
            BrilyfWidgets.frameRenderingQueued(  );
    }

    
bool frameEnded( const FrameEvent& evt );

    BrilyfWidgets mWidgets[
16];
}
;

posted on 2008-09-24 22:11 brilyf 阅读(2117) 评论(2)  编辑 收藏 引用

评论

# re: Ogre在游戏开发中逐帧更新  回复  更多评论   

这是开了两个线程吗?
一个做DP和flip
另一个回调frameRenderingQueued
2008-09-25 08:49 | LOGOS

# re: Ogre在游戏开发中逐帧更新  回复  更多评论   

呵呵,ogre系统好象是这样的.
2008-09-25 10:35 | brilyf

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