Ogre监听框架构成:
Ogre主要通过继承FrameListener来完成监听系统的输入并变化场景内容的功能,对于非控制性的变化,Ogre也可以通过类ExampleFrameListener来完成
在FrameListener中,主要有以下的方法:
--------------------------------------------------------------------------------------------------
1. Virtual bool frameStarted(const FrameEvent&evt){return true};
帧渲染之前的事件处理方法,发生在即将要进行渲染的时候,返回值为帧就可以继续渲染,为假说明要终止当前的渲染循环。
2. Virtual bool frameRenderingQueued(const FrameEvent & evt){(void)evt;return true};
发生在所有的渲染目标都已经就绪,但是窗口还没有交换缓存之前,
3. Virtual bool frameEnded(const FrameEvent &evt){return ture};
帧渲染之后的事件处理方法,在一个帧正在被渲染的时候调用,这个时间发生在所有的渲染目标都已经完全更新并且缓存已经交换的时候
--------------------------------------------------------------------------------------------------
Ogre引擎在渲染过程中的每一帧之前调用frameStarted方法,而之后会调用frameEnded方法,通过这种方式,可以再渲染期间对场景物体(包括摄像机)进行移动、缩放等控制,当然也可以完成其他的处理 。
而frameStarted和frameEnded都以FrameEvent为参数,在FrameListener中,定义了如下的FrameEvent结构来表示一次帧渲染时事件,在这个结构中定义的两个元素时间可以方便我们对于帧事件的处理:
Struct FrameEvent
{
Real timeSinceLastEvent;
上一次时间发生到当前时间点所过去的时间(秒),一个frameStarted到frameEnded之间或 一个FrameEnded到FrameStarted之间过去的时间(这个时间不是瞬时值而是一个在当前已有帧之间的平均值)
Real timeSinceLastFrame;
两个相同类型时间之间过去的时间(秒),两个frameStarted或者两个frameEnded之间的时间,也就是一个完整的帧花去的时间(这同样是一个类似已发生帧之间的平均值)
}
“Listener”是一个设计来响应程序的特殊事件,唤醒回调过程的类,为了得到对于帧事件的有序响应,使用者必须要创建一个frameListener 的子类,并覆盖其中的响应方法。使用Root::addFrameListener传递一个此类的实例,这种注册是没有限制的,用户可以为不同的需要注册不同的监听,但是这都需要在一个帧监听循环中发生,否则监听只对于一个渲染目标是有用的。
帧监听器对于输入事件的处理方法有良好总模式:立即模式和缓冲模式。
1. 立即模式——适合于3D场景漫游过程,当在每一帧的渲染之前,系统捕获输入设备状态,并根据这些状态对于场景中的物体进行控制。
2. 缓冲模式——适合于GUI界面的情况(如设置菜单),输入设备状态可以被发送到各个GUI元素进行处理(如按钮被按下)。
ExampleFrameListener(继承自frameListener,例子程序中的主要使用监听基类)中的主要成员函数
1. Virtual void updateStates(void)
更新状态的函数,主要是完成overlay的 元素的状态显示更新
2. 构造函数
ExampleFrameListener(RenderWindow *win,Camera *cam,bool BufferedKeys=false,bool bufferedMouse=false,bool bufferedJoy=false);
传入参数很多,主要是给类中的成员注册信息,然后是初始化一些句柄内容
3. 如果是可以硬件加速的就可以使用processShaderGeneratorInput()函数来实现对于键盘鼠标的响应
4. 在类中还有windowResized(RenderWindow *rw)函数来进行窗口的裁剪区域的调整,主要是窗口的大小和鼠标位置的调整,这个函数在ExampleFrameListener的构造函数中被调用
5. 通过在析构函数中调用windowClosed(RenderWindow *rw)函数可以实现窗口的销毁
(主要是销毁鼠标键盘和操纵杆,最后不要忘记还要将InputManager销毁)
6. 在ExampleFrameListener的析构函数中主要是将窗口与本listener解绑定,然后完成窗口的销毁工作
1