进入主循环 void Root::startRendering(void) { assert(mActiveRenderer != 0); mActiveRenderer->_initRenderTargets(); // Clear event times clearEventTimes(); // Infinite loop, until broken out of by frame listeners // or break out by calling queueEndRendering() mQueuedEnd = false; while( !mQueuedEnd ) { //Pump messages in all registered RenderWindow windows WindowEventUtilities::messagePump(); if (!renderOneFrame()) break; } } 渲染一帧 bool Root::renderOneFrame(void) { if(!_fireFrameStarted()) return false; if (!_updateAllRenderTargets()) return false; return _fireFrameEnded(); } 一帧开始事件 bool Root::_fireFrameStarted() { FrameEvent evt; populateFrameEvent(FETT_STARTED, evt); return _fireFrameStarted(evt); } bool Root::_fireFrameStarted(FrameEvent& evt) { OgreProfileBeginGroup("Frame", OGREPROF_GENERAL); // Remove all marked listeners set<FrameListener*>::type::iterator i; for (i = mRemovedFrameListeners.begin(); i != mRemovedFrameListeners.end(); i++) { mFrameListeners.erase(*i); } mRemovedFrameListeners.clear(); // Tell all listeners for (i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i) { if (!(*i)->frameStarted(evt)) return false; } return true; } 帧队列事件 bool Root::_updateAllRenderTargets(void) { // update all targets but don't swap buffers mActiveRenderer->_updateAllRenderTargets(false); // give client app opportunity to use queued GPU time bool ret = _fireFrameRenderingQueued(); // block for final swap mActiveRenderer->_swapAllRenderTargetBuffers(mActiveRenderer->getWaitForVerticalBlank()); // This belongs here, as all render targets must be updated before events are // triggered, otherwise targets could be mismatched. This could produce artifacts, // for instance, with shadows. for (SceneManagerEnumerator::SceneManagerIterator it = getSceneManagerIterator(); it.hasMoreElements(); it.moveNext()) it.peekNextValue()->_handleLodEvents(); return ret; } bool Root::_fireFrameRenderingQueued() { FrameEvent evt; populateFrameEvent(FETT_QUEUED, evt); return _fireFrameRenderingQueued(evt); } bool Root::_fireFrameRenderingQueued(FrameEvent& evt) { // Increment next frame number ++mNextFrame; // Remove all marked listeners set<FrameListener*>::type::iterator i; for (i = mRemovedFrameListeners.begin(); i != mRemovedFrameListeners.end(); i++) { mFrameListeners.erase(*i); } mRemovedFrameListeners.clear(); // Tell all listeners for (i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i) { if (!(*i)->frameRenderingQueued(evt)) return false; } return true; } 一帧结束事件 bool Root::_fireFrameEnded() { FrameEvent evt; populateFrameEvent(FETT_ENDED, evt); return _fireFrameEnded(evt); } bool Root::_fireFrameEnded(FrameEvent& evt) { // Remove all marked listeners set<FrameListener*>::type::iterator i; for (i = mRemovedFrameListeners.begin(); i != mRemovedFrameListeners.end(); i++) { mFrameListeners.erase(*i); } mRemovedFrameListeners.clear(); // Tell all listeners bool ret = true; for (i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i) { if (!(*i)->frameEnded(evt)) { ret = false; break; } } // Tell buffer manager to free temp buffers used this frame if (HardwareBufferManager::getSingletonPtr()) HardwareBufferManager::getSingleton()._releaseBufferCopies(); // Tell the queue to process responses mWorkQueue->processResponses(); OgreProfileEndGroup("Frame", OGREPROF_GENERAL); return ret; }