代码基于1.7.3版本。整个scene的渲染堆栈如下
Root::startRendering()
Root::renderOneFrame()
Root::_updateAllRenderTargets()
RenderSystem::_updateAllRenderTargets()
RenderTarget::update()
RenderTarget::updateImpl()
RenderTarget::_updateAutoUpdated()
D3D9RenderWindow::_updateViewport()
RenderTarget::_updateViewport()
Viewport::update()
Camera::_renderScene() --这里在调用下面的两边,分别是呼叫listener的cameraPreRenderScene()和cameraPostRenderScene()
SceneManager::_renderScene()
也就是说,SceneManager::_renderScene()负责整个场景的渲染。在这个方法中:
1、查看阴影是否开启,如果开启,则做一些初始化
if (isShadowTechniqueInUse())
{
// Prepare shadow materials
initShadowVolumeMaterials();
}
2、测试可以影响到视景体的灯
// Locate any lights which could be affecting the frustum
findLightsAffectingFrustum(camera);
// Are we using any shadows at all?
if (isShadowTechniqueInUse() && vp->getShadowsEnabled())
{
// Prepare shadow textures if texture shadow based shadowing
// technique in use
if (isShadowTechniqueTextureBased())
{
OgreProfileGroup("prepareShadowTextures", OGREPROF_GENERAL);
// *******
// WARNING
// *******
// This call will result in re-entrant calls to this method
// therefore anything which comes before this is NOT
// guaranteed persistent. Make sure that anything which
// MUST be specific to this camera / target is done
// AFTER THIS POINT
prepareShadowTextures(camera, vp); --此处生成shadow texture?No,因为世界坐标还没有更新到?
// reset the cameras & viewport because of the re-entrant call
mCameraInProgress = camera;
mCurrentViewport = vp;
}
}
3、然后是进行大多数情况下的oct tree的场景节点更新,主要是每个节点的物体更新出世界坐标和世界坐标下的包围盒等。
_updateSceneGraph(camera);
//octtree的_updateSceneGraph直接调用下面的
void SceneManager::_updateSceneGraph(Camera* cam)
{
// Process queued needUpdate calls
Node::processQueuedUpdates();
// Cascade down the graph updating transforms & world bounds
// In this implementation, just update from the root
// Smarter SceneManager subclasses may choose to update only
// certain scene graph branches
getRootSceneNode()->_update(true, false);
}
4、预先准备render Queue,PVS生成
// Prepare render queue for receiving new objects
{
OgreProfileGroup("prepareRenderQueue", OGREPROF_GENERAL);
prepareRenderQueue();
}
if (mFindVisibleObjects)
{
OgreProfileGroup("_findVisibleObjects", OGREPROF_CULLING);
// Assemble an AAB on the fly which contains the scene elements visible
// by the camera.
CamVisibleObjectsMap::iterator camVisObjIt = mCamVisibleObjectsMap.find( camera );
assert (camVisObjIt != mCamVisibleObjectsMap.end() &&
"Should never fail to find a visible object bound for a camera, "
"did you override SceneManager::createCamera or something?");
// reset the bounds
camVisObjIt->second.reset();
// Parse the scene and tag visibles
firePreFindVisibleObjects(vp);
_findVisibleObjects(camera, &(camVisObjIt->second),
mIlluminationStage == IRS_RENDER_TO_TEXTURE? true : false);
firePostFindVisibleObjects(vp);
mAutoParamDataSource->setMainCamBoundsInfo(&(camVisObjIt->second));
}
5、帧更新
// Begin the frame
mDestRenderSystem->_beginFrame();
// Set rasterisation mode
mDestRenderSystem->_setPolygonMode(camera->getPolygonMode()); --各种可能的polygon 模式设置
// Set initial camera state
mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrixRS());