按照經(jīng)典的Qt程序結(jié)構(gòu),應(yīng)該有一個(gè)從QMainWindow繼承而來(lái)的MainWindow,讓它做為主窗口,然后子類化一個(gè)QWidget,它做為主窗口的"中心掛件",能過(guò)封裝Ogre的部分功能,實(shí)現(xiàn)用Ogre對(duì)該窗體的繪制。首先,如何把Ogre這個(gè)引擎發(fā)動(dòng),不斷驅(qū)動(dòng)其進(jìn)行工作。Qt也需要告訴Ogre如何把渲染的內(nèi)容畫到指定的窗口中去,以及用哪種方式更新窗口中的內(nèi)容。當(dāng)鍵盤或鼠標(biāo)消息來(lái)的時(shí)候,如何通知Ogre進(jìn)行響應(yīng)。從Ogre這邊來(lái)看,就是如何把Ogre的功能,分布到Qt的各個(gè)部分。而且與一般的ogre程序不同,不是進(jìn)入到連續(xù)的循環(huán)中(一般的ogre程序中,通過(guò)執(zhí)行mRoot->startRendering();語(yǔ)句進(jìn)入一個(gè)不停渲染循環(huán),通過(guò)預(yù)先安插好的幀偵聽器來(lái)對(duì)消息進(jìn)行響應(yīng),對(duì)程序邏輯進(jìn)行處理)而可以是“必要時(shí)”對(duì)窗口進(jìn)行更新。而且與一般ogre程序不同,由于Qt自身可以檢測(cè)輸入設(shè)備消息,因此,OIS不再需要。把Ogre中的內(nèi)容嵌入到Qt,從形式來(lái)看可以許多種,也就是說(shuō)可以把相關(guān)Ogre的部分拆成不同部分,按照作者的需要封裝在Qt中的不同部分。比如,Ogre中描述抽象的“引擎”概念的部分(Root等),因?yàn)槲覀兿胍坏珣?yīng)用程序啟動(dòng),就應(yīng)該讓Ogre引擎啟動(dòng)了,那么這些部分可以用QApplication封裝,而且RenderWindow,與Qt中的QWidget概念上是關(guān)聯(lián)的,所以就用QWidget來(lái)封裝。出于簡(jiǎn)單的原因,我把Ogre都封裝從QWidget繼承而來(lái)的OgreView中了。很顯然,主要考慮OgreView就可以了。
class OgreView : public QWidget
{
Q_OBJECT
public:
OgreView(QWidget* parent );
~OgreView();
//QSize minimumSizeHint() const;
//QSize sizeHint() const;
protected:
void setupView()//創(chuàng)建Ogre使用的內(nèi)容,場(chǎng)景內(nèi)容;
void update();//通過(guò)它,手動(dòng)更新場(chǎng)景內(nèi)容
void setupResources();//
void createScene();
void createLight();
void resizeEvent(QResizeEvent* evt);//窗口可能縮放
void timerEvent(QTimerEvent* evt);//可以設(shè)一時(shí)鐘來(lái)更新窗口
void paintEvent(QPaintEvent* evt);//呵,當(dāng)然得處理了
//消息響應(yīng)
void keyPressEvent(QKeyEvent* evt);
void keyReleaseEvent(QKeyEvent* evt);
void mousePressEvent(QMouseEvent* evt);
void mouseReleaseEvent(QMouseEvent* evt);
void mouseMoveEvent(QMouseEvent* evt);
void wheelEvent(QWheelEvent* evt);
//有關(guān)Ogre
Ogre::RenderWindow* mRenderWindow;
Ogre::SceneManager* mSceneMgr;
Ogre::Camera* mCamera;
Ogre::Viewport* mVp;
Ogre::Root* mRoot;
Ogre::Light* mainLight;
Ogre::Entity* mainEnt;
Ogre::SceneNode* mainNode;
//一些控制變量,沒(méi)有完全列出
Ogre::Vector3 mDirection;
Ogre::Real mRotate;
};
//cpp文件中的內(nèi)容(部分)
OgreView::OgreView(QWidget* parent) : QWidget(parent,Qt::WFlags(Qt::MSWindowsOwnDC))
{
mRenderWindow = NULL;
mSceneMgr = NULL;
mVp = NULL;
mainEnt = NULL;
mainNode = NULL;
//....還有一些控制變量的初始化
setupResources();
}
OgreView::~OgreView()
{
// destroy Viewport and RenderWindow
if( mVp )
{
mRenderWindow->removeViewport(mVp->getZOrder());
mVp = 0;
}
Ogre::Root::getSingleton().detachRenderTarget(mRenderWindow);
mRenderWindow = 0;
if(mRoot != NULL){
delete mRoot;
mRoot = 0;
}
}
void OgreView::setupResources()
{
mRoot = new Ogre::Root();
Ogre::ConfigFile cf;
cf.load("resources.cfg");
Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
Ogre::String secName, typeName, archName;
while(seci.hasMoreElements())
{
secName = seci.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap* settings = seci.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for(i=settings->begin(); i!=settings->end(); ++i){
typeName = i->first;
archName = i->second;
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);
}
}
if(!mRoot->restoreConfig())
{
mRoot->showConfigDialog();
}
mRoot->initialise(false);
//以上都是從Ogre普通程序照搬
}
//沒(méi)啥說(shuō)的,代碼比注釋更明白
void OgreView::createScene()
{
mainEnt = mSceneMgr->createEntity("Head", "ogrehead.mesh");
mainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mainNode->attachObject(mainEnt);
}
void OgreView::createLight()
{
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
mainLight = mSceneMgr->createLight("MainLight");
mainLight->setPosition(20,80,50);
}
void OgreView::setupView()
{
if(mRenderWindow)
return;
//createRenderWindow,當(dāng)然必須得自己手工建窗口了,把窗口句柄扒出來(lái)....
Ogre::NameValuePairList params;
params["externalWindowHandle"] = Ogre::StringConverter::toString((size_t)(HWND)winId());
mRenderWindow = mRoot->createRenderWindow("View", width(), height(), false, ¶ms);
//SceneManager
mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
//setup camera & viewport
mCamera = mSceneMgr->createCamera("PlayerCam");
mCamera->setPosition(Ogre::Vector3(0,0,80));
mCamera->lookAt(Ogre::Vector3(0,0,-300));
mCamera->setNearClipDistance(5);
mVp = mRenderWindow->addViewport(mCamera);
mVp->setBackgroundColour(Ogre::ColourValue(0, 0.0, 0.0, 1));
mCamera->setAspectRatio(Ogre::Real(mVp->getActualWidth()) / Ogre::Real(mVp->getActualHeight()));
//resource
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
createScene();
createLight();
startTimer(2);
}
void OgreView::paintEvent(QPaintEvent *evt)
{
Q_UNUSED(evt);
if(mRenderWindow == NULL)
setupView();
update();
}
void OgreView::timerEvent(QTimerEvent* evt)
{
Q_UNUSED(evt);
update();
}
void OgreView::update()
{
//手工更新場(chǎng)景內(nèi)容,而不是進(jìn)入到連續(xù)的循環(huán)中
if(mRenderWindow != NULL){
mRoot->_fireFrameStarted();
mRenderWindow->update();
mCamera->moveRelative(mDirection);
mCamera->yaw(Ogre::Radian(angleX));
mCamera->pitch(Ogre::Radian(angleY));
mRoot->_fireFrameEnded();
}
}
void OgreView::resizeEvent(QResizeEvent *evt)
{
Q_UNUSED(evt);
if (mRenderWindow != NULL){
mRenderWindow->windowMovedOrResized();
mCamera->setAspectRatio(Ogre::Real(mVp->getActualWidth()) / Ogre::Real(mVp->getActualHeight()));
}
}
void OgreView::keyPressEvent(QKeyEvent* evt)
{
if(mainEnt != NULL && mainNode != NULL){
switch(evt->key()){
case Qt::Key_W:
case Qt::Key_Up:
rotX = -0.1;
mainNode->pitch(Ogre::Radian(rotX));
break;
case Qt::Key_S:
case Qt::Key_Down:
rotX = 0.1;
mainNode->pitch(Ogre::Radian(rotX));
break;
case Qt::Key_A:
case Qt::Key_Left:
rotY = -0.1;
mainNode->yaw(Ogre::Radian(rotY));
break;
case Qt::Key_D:
case Qt::Key_Right:
rotY = 0.1;
mainNode->yaw(Ogre::Radian(rotY));
break;
}
}
}
void OgreView::mousePressEvent(QMouseEvent* evt)
{
if(evt->button() == Qt::LeftButton)
mouseLeftPressed = true;
if(evt->button() == Qt::RightButton){
mouseRightPressed = true;
mousePos = Ogre::Vector2(evt->x(), evt->y());
}
if(evt->button() == Qt::MidButton)
mouseMiddleBtn = true;
}
void OgreView::wheelEvent(QWheelEvent* evt)
{
mDirection.z = -evt->delta()/12;
update();
mDirection.z = 0;
}
posted on 2007-05-21 11:57
清源游民 閱讀(8333)
評(píng)論(18) 編輯 收藏 引用 所屬分類:
OGRE 、
Qt