(注:本文假设你读过前三节)
使用COgreSceneBox只能对一个Static进行3D场景的渲染,如何对多个Static同时进行3D渲染呢?改动的步骤很直观:
1. 先尝试建立多个COgreSceneBox的对象,编译。。。运行。。。,结果窗口没出来就弹出了一个断言错误, ms_Singleton != 0,为什么会这样呢?这要从OGRE的内部设计分析,OGRE将Root对象派生于Singleton模版,熟悉设计模式的程序员都知道Root实际上被设计成了单件模式,也就是只能有一个对象。
2. 既然知道Root只能有一个对象,那么所有对Root的初始化和释放操作都必须只运行一次,根据这个对COgreSceneBox的代码进行改动:
// Init ogre

BOOL Initialize()

...{
// already inited
FALSE_RETURN( (m_pRoot == NULL), TRUE );

T* pT = static_cast<T*>(this);

if(Root::getSingletonPtr() == NULL)

...{
// create scene root with no config file and plugin
m_pRoot = new Root("", "");

// Load plugin
FALSE_RETURN( pT->LoadPlugin(), FALSE );

// Select Render System
FALSE_RETURN( pT->SelectRenderSystem(), FALSE );

m_pRoot->initialise(false, TBase::GetWndClassName());

// Load Resource
FALSE_RETURN( pT->LoadResource(), FALSE );
}
else

...{
m_pRoot = Root::getSingletonPtr();
}

// Create Render Window
FALSE_RETURN( pT->CreateRenderWindow(), FALSE );

// Create Scene Manager
FALSE_RETURN( pT->CreateSceneManager(), FALSE );

// Create Default Camera and Viewport
FALSE_RETURN( pT->CreateDefaultCamera(), FALSE );

ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

// Create Scene
FALSE_RETURN( pT->CreateScene(), FALSE );

return TRUE;
}
代码将 加载插件、选择渲染系统、加载资源 放到if()...else()判断中,使这些代码只执行一次,这里多嘴一句,OGRE好像只能在同一个Root中使用同一种渲染系统(OpenGL/D3D),无法在同一时刻使用两种系统,甚至在系统切换时需要重新构建所有资源和窗口。
3. 改动代码后我们再编译、运行(这里我多加了5个Static,每个static控件对应一个COgreSceneBox的对象),OK,出来了!但是关闭的时候出了个问题:又是ms_Singleton的断言错误,仔细想了一下,肯定是释放的时候多次delete了,于是像构造一样确保Root的释放只发生一次(我的处理方案是在整个程序退出时释放Root),OK,这次应该没有什么问题了。
为了演示效果,我从COgreSceneBox派生了一个类CExampleSceneBox,让原来静止的食人魔以一定速度绕Y轴旋转,下图是6个食人魔,由六个static控件分别渲染,并以不同的速率和方向进行旋转:
