Ogre中有许多监听类,我们可以简单理解成C#中的事件,这些类作用都不小,说大点可能改变流程,说小点修改参数等,下面列举一些常用的监听类.
- FrameListener:由Ogre中的Root负责维护,主要针对所有RenderTarget监听
- frameStarted:在一桢开始的时候,所有RenderTarget更新之前.
- frameRenderingQueued:所有RenderTarget更新之后,但是还没交换缓冲区.(意思屏幕上显示没变)
- frameEnded:所有RenderTarget更新并交换了缓冲区数据.
- RenderTargetListener:由RenderTarget负责维护,主要针对当前RenderTarget监听
- preRenderTargetUpdate:在Viewport开始更新之前,可以用来根据不同的RenderTarget改变Renderable的可见性,摄像机位置.或是捕获当前RenderTarget做别的处理.
- postRenderTargetUpdate:在Viewport更新之后,一般用来还原在preRenderTargetUpdate做的处理.
- preViewportUpdate:在上面的preRenderTargetUpdate之后,SceneManger开始渲染之前.可以针对viewport修改.
- postViewportUpdate:在postRenderTargetUpdate之前,可以还原preViewportUpdate所做更改.
- SceneManager::Listener:由SceneManager负责维护,针对场景节点更新,场景模型可见,阴影
- preUpdateSceneGraph:在上面viewport开始更新后,SceneManager开始更新结果,由RootSceneNode递归更新.
- postUpdateSceneGraph:如上所有节点更新完后.在去查找模型可见之前.
- preFindVisibleObjects:更新节点后,开始查找Renderable可见之前.
- postFindVisibleObjects:在所有可见的Renderable添加见渲染通道之后.
- shadowTexturesUpdated:以及下面的几个方法主要是关于阴影的更新,这里不细说,以后细说阴影部分.
- MaterialManager::Listener:由MaterialManager负责维护,能针对Viewport提供多方案.
- handleSchemeNotFound:在查找所有可见的Renderable中,也就是添加在渲染通道的时候,查找对应Renderable的材质,是否和当前的方案一致,如不一致发生.
- RenderQueueListener:由SceneManager负责维护,提供针对每组渲染通道设置.
- preRenderQueues:开始渲染通道里的Renderable.所有通道组开始渲染之前.
- postRenderQueues:所有渲染通道里的Renderable都渲染之后.
- renderQueueStarted:同组的渲染通道开始渲染.preRenderQueues有多组渲染通道,在之后针对每组渲染.
- renderQueueEnded:当前组的渲染通道渲染完后.
- RenderObjectListener:由SceneManager负责维护,提供渲染时当前Renderable与Pass.
- notifyRenderSingleObject:,在进入通道后,在渲染Renderable之前.其中RTSS就用来更新当前着色器参数.
- CompositorInstance::Listener:由CompositorInstance负责维护,主要用于修改当前合成器的着色器参数.
- notifyMaterialSetup:在RenderSystemOperation刚创建时,一般用于修改不变的着色器参数.
- notifyMaterialRender:RenderSystemOperation每次更新调用,一般用来每桢要更新参数.
- createResources:在createResources(创建当前CompositorInstance中的RenderTexture)后.
- Viewport::Listener:由Viewport负责维护,主要检查当前viewport一些变化.
- viewportCameraChanged:当前Viewport上摄像机变化后.
- viewportDimensionsChanged:当前Viewport尺寸变化.
- viewportDestroyed:当前Viewport析构时发生.
如上这些是一些基本的监听类,还有一些没有列举出来.上面虽然大致说了那些监听事件在那调用,但是大家肯定也感觉不清晰,如下结合渲染流程来说,大家就会有个比较清楚的认识.
如下是正常的渲染流程,大致说下主要过程,Root调用srartRendering开始渲染,每桢更新,在每桢中查找当前所有的RenderTarget,更新当前RenderTarget,然后交给viewport,camera到SceneManager,场景首先更新根节点下所有节点位置, 更新参数mAutoParamDataSource一部分已知参数,然后检查所有节点上的MovableObject是否可见,如果可见,把MovableObject对应的Renderable和pass根据渲染等级加入渲染通道组.(说下渲染等级RenderQueueGroupID,一般是从0到105,0是背景,100是UI,就是说RenderQueueGroupID越大,越在上面显示.)然后由渲染等级由低到高开始渲染通道内的Renderable,然后结束本桢.如下是一些主要的渲染过程.
- Root::startRendering->Root::renderOneFrame
- Root::_fireFrameStarted(FrameListener::frameStarted)
- Root::_updateAllRenderTargets 开始更新所有RenderTarget
- RenderSystem::_updateAllRenderTargets
- RenderTarget::update->RenderTarget::updateImpl 更新当前的RenderTarget
- RenderTarget::_beginUpdate(RenderTargetListener::preRenderTargetUpdate)
- RenderTarget::_updateViewport
- RenderTarget::fireViewportPreUpdate(RenderTargetListener::preViewportUpdate)
- Viewport::update->Camera::_renderScene
- Camera::Listener::cameraPreRenderScene
- SceneManger::_renderScene
- SceneManger::_updateSceneGraph
- SceneManger::firePreUpdateSceneGraph(SceneManager::Listener::preUpdateSceneGraph)
- Node::processQueuedUpdate
- RootSceneNode::_update(true,false)
- SceneManger::firePostUpdateSceneGraph(SceneManager::Listener::postUpdateSceneGraph)
- SceneManager::setViewport
- RenderSystem::_setViewport
- RenderSystem::_setRenderTarget (设定渲染的RenderTarget)
- MaterialManager::setActiveScheme
- RenderSystem::_setViewport
- SceneManger::firePreFindVisibleObjects(SceneManager::Listener::preFindVisibleObjects)
- SceneManger::_findVisibleObjects(父节点,第一次为根节点)
- SceneNode::_findVisibleObjects
- RenderQueue::processVisibleObject(MovableObject)
- MovableObject::_notifyCurrentCamera
- Renderable::Visitor::visitor
- MovableObject::_updateRenderQueue
- RenderQueue::addRenderable
- Renderable::getTechnique(如果没找到当前方案,执行下面二句)
- MaterialManager:: _arbitrateMissingTechniqueForActiveScheme
- MaterialManager::Listener::handleSchemeNotFound
- QueuedRenderableCollection::addRenderable(Pass,Renderable)
- SceneNode:: _findVisibleObjects (子节点)
- SceneManger::firePostFindVisibleObjects(SceneManager::Listener::postFindVisibleObjects)
- RenderSystem::_beginFrame
- SceneManager::_renderVisibleObjects
- SceneManager::firePreRenderQueues(RenderQueueListener::preRenderQueues)
- SceneManager::fireRenderQueueStarted(RenderQueueListener::renderQueueStarted)
- SceneMangger::renderObjects ->QueuedRenderableCollection::acceptVisitorGrouped
- SceneManager::SceneMgrQueuedRenderableVisitor::visit
- SceneManager::renderSingleObject
- RenderSystem::fireRenderSingleObject(RenderObjectListener::notifyRenderSingleObject)
- SceneManager::updateGpuProgramParameters
- Renderable::getRenderOperation
- Renderable::preRender
- RenderSystem::_render
- Renderable::postRender
- SceneMangger::renderObjects ->QueuedRenderableCollection::acceptVisitorGrouped
- SceneManager::fireRenderQueueEnded(RenderQueueListener::renderQueueEnded)
- SceneManager::firePostRenderQueues(RenderQueueListener::postRenderQueues)
- RenderSystem::_endFrame
- SceneManger::_updateSceneGraph
- Camera::Listener::cameraPostRenderScene
- RenderTarget::fireViewportPostUpdate(RenderTargetListener::postViewportUpdate)
- RenderTarget::_endUpdate(RenderTargetListener::postRenderTargetUpdate)
- Root::_fireFrameRenderingQueued(FrameListener:: frameRenderingQueued)
- RenderSystem::_swapAllRenderTargetBuffers
- RenderSystem::_updateAllRenderTargets
- Root::_fireFrameEnded(FrameListener:: frameEnded)
如果Ogre启用Compositor后,有些位置需要改变了,前篇Ogre Compositor解析里有简单介绍过CompositorChain实现了接口RenderTargetListener与Viewport::Listener,那么在上面3.1.2 RenderTarget::_beginUpdate中就捕捉到当前的RenderTarget,并且调用CompositorChain的compile,生成当前TargetOperation列表,RenderSystemOperation列表,在TargetOperation的RenderTarget更新时,指定对应的TargetOperation到RenderQueueListener中,这样在渲染通道时,执行当前TargetOperation下的所有RenderSystemOperation,然后开始渲染.
- RenderTarget::_beginUpdate(RenderTargetListener::preRenderTargetUpdate)
- CompositorChain::_compile
- CompositorChain::_complieTargetOperations
- CompositorChain::_complieTargetOperations (compiledState收集TargetOperation)
- CompositorChain::collectPasses(queueRenderSystemOp收集RenderSystemOperation)
- new RenderSystemOperation(根据CompositionTargetPass的type传入生成不同对象)
- CompositorInstance::_fireNotifyMaterialSetup(CompositorInstance::Listener::notifyMaterialSetup)
- CompositorChain::_complieTargetOperations
- TargetOperation->RenderTarget::update(一个CompositorChain里有多个TargetOperation)
- CompositorChain::preTargetOperation(指定当前TargetOperation, RenderSystemOperation到CompositorChain::RQListener)
- 同上面流程RenderTarget::update 到SceneManager::_renderVisibleObjects
- SceneManager::firePreRenderQueues(RenderQueueListener::preRenderQueues)
- SceneManager::fireRenderQueueStarted(RenderQueueListener::renderQueueStarted)
- CompositorChain::RQListener::flushUpTo(执行所有RenderSystemOperation)
- RenderSystemOperation::execute
- CompositorInstance:: _fireNotifyMaterialRender(CompositorInstance::Listener:: notifyMaterialRender)
- RenderSystemOperation::execute
- CompositorChain::RQListener::flushUpTo(执行所有RenderSystemOperation)
- 检查skipThisQueue == true -> 跳过本级别(同RenderQueueGroupID)的SceneMangger::renderObjects,否则同原过程一样.
- SceneManager::firePostRenderQueues(RenderQueueListener::postRenderQueues)
- TargetOperation->RenderTarget::swapBuffers-> (如果选用RTT用FBO)GLFBORenderTexture::swapBuffers
- CompositorChain::_compile
- RenderTarget::_endUpdate(RenderTargetListener::postRenderTargetUpdate)
以上渲染过程都只是一般情况下的,不是固定的,我们本身就可以修改其中一些过程,还有用户可以自己手动渲染Renderable,这些都会造成原来渲染流程变化.
本文比较简单,但是相关流程是整个Ogre的核心,掌握上面的流程与监听事件,我们才能更好的使用Ogre.