用Ogre實(shí)現(xiàn)畫中畫 [ 截圖 ]
Posted on 2008-08-04 17:22 RichardHe 閱讀(2894) 評(píng)論(2) 編輯 收藏 引用 所屬分類: OGRE在玩一些3D游戲的時(shí)候,經(jīng)常會(huì)有畫中畫的功能,比如“跑跑卡丁車”、“殺手十三”等等,于是想自己動(dòng)手試驗(yàn)一下。
普 通情況下,我們使用單一的攝像機(jī),實(shí)現(xiàn)第一人稱或者第三人稱,有時(shí)我們用多個(gè)攝像機(jī)在單一的窗口中切換視角,比如從第一人稱切換到第三人稱視角(游戲中屢 見不鮮),而畫中畫將會(huì)同時(shí)展現(xiàn)第一人稱和第三人稱(或者第三人稱與第三人稱),也就是說同時(shí)存在不同的觀察點(diǎn),這就需要多窗口多攝像機(jī)分別進(jìn)行渲染。
用Ogre實(shí)現(xiàn)畫中畫功能是件比較容易的事情,首先,搭建一個(gè)普通的場(chǎng)景,關(guān)于這方面的工作www.ogre3d.org/wiki里有詳細(xì)的教程,不贅述了。
下面進(jìn)入關(guān)鍵部分。
在Ogre里攝像機(jī)Camera和視口Viewport是一一對(duì)應(yīng)的關(guān)系,普通情況下包含一個(gè)攝像機(jī)對(duì)應(yīng)一個(gè)視口,我們只要添加攝像機(jī)和與之對(duì)應(yīng)的視口就OK了!
我的窗口類里是這樣配置Ogre的,基本和教程示例里的一樣。
鷹眼是什么?不是指小地圖,玩一玩跑跑卡丁車就明白我說的畫中畫是什么了 回復(fù) 更多評(píng)論
普 通情況下,我們使用單一的攝像機(jī),實(shí)現(xiàn)第一人稱或者第三人稱,有時(shí)我們用多個(gè)攝像機(jī)在單一的窗口中切換視角,比如從第一人稱切換到第三人稱視角(游戲中屢 見不鮮),而畫中畫將會(huì)同時(shí)展現(xiàn)第一人稱和第三人稱(或者第三人稱與第三人稱),也就是說同時(shí)存在不同的觀察點(diǎn),這就需要多窗口多攝像機(jī)分別進(jìn)行渲染。
用Ogre實(shí)現(xiàn)畫中畫功能是件比較容易的事情,首先,搭建一個(gè)普通的場(chǎng)景,關(guān)于這方面的工作www.ogre3d.org/wiki里有詳細(xì)的教程,不贅述了。
下面進(jìn)入關(guān)鍵部分。
在Ogre里攝像機(jī)Camera和視口Viewport是一一對(duì)應(yīng)的關(guān)系,普通情況下包含一個(gè)攝像機(jī)對(duì)應(yīng)一個(gè)視口,我們只要添加攝像機(jī)和與之對(duì)應(yīng)的視口就OK了!
我的窗口類里是這樣配置Ogre的,基本和教程示例里的一樣。
bool BaseApplication::setup(void)
{
mRoot = new Root();
// 設(shè)置資源
setupResources();
// 配置渲染窗口
bool carryOn = configure();
if (!carryOn)
return false;
// 創(chuàng)建場(chǎng)景管理器
chooseSceneManager();
// 創(chuàng)建攝像機(jī)
createCamera();
// 創(chuàng)建視口
createViewports();
// 設(shè)置缺省 mipmap 等級(jí)
TextureManager::getSingleton().setDefaultNumMipmaps(5);
// 創(chuàng)建所有資源監(jiān)聽器(為了加載屏幕)
createResourceListener();
// 加載資源
loadResources();
// 創(chuàng)建場(chǎng)景
createScene();
// 創(chuàng)建幀監(jiān)聽器
createFrameListener();
return true;
}
{
mRoot = new Root();
// 設(shè)置資源
setupResources();
// 配置渲染窗口
bool carryOn = configure();
if (!carryOn)
return false;
// 創(chuàng)建場(chǎng)景管理器
chooseSceneManager();
// 創(chuàng)建攝像機(jī)
createCamera();
// 創(chuàng)建視口
createViewports();
// 設(shè)置缺省 mipmap 等級(jí)
TextureManager::getSingleton().setDefaultNumMipmaps(5);
// 創(chuàng)建所有資源監(jiān)聽器(為了加載屏幕)
createResourceListener();
// 加載資源
loadResources();
// 創(chuàng)建場(chǎng)景
createScene();
// 創(chuàng)建幀監(jiān)聽器
createFrameListener();
return true;
}
其中,createCamera(); // 創(chuàng)建攝像機(jī) 和 createViewports(); // 創(chuàng)建視口 是我們需要關(guān)心的。
createCamera():
void BaseApplication::createCamera(void)
{
// 主窗口攝像機(jī)
mCamera_1 = mSceneMgr->createCamera("Cam_1");
mCamera_1->setPosition(Vector3(0,0,300));
mCamera_1->lookAt(Vector3(0,0,-300));
mCamera_1->setNearClipDistance(5);
// 畫中畫攝像機(jī)
mCamera_2 = mSceneMgr->createCamera("Cam_2");
mCamera_2->setPosition(Vector3(100,100,300));
mCamera_2->lookAt(Vector3(-100,-100,-300));
mCamera_2->setNearClipDistance(5);
}
{
// 主窗口攝像機(jī)
mCamera_1 = mSceneMgr->createCamera("Cam_1");
mCamera_1->setPosition(Vector3(0,0,300));
mCamera_1->lookAt(Vector3(0,0,-300));
mCamera_1->setNearClipDistance(5);
// 畫中畫攝像機(jī)
mCamera_2 = mSceneMgr->createCamera("Cam_2");
mCamera_2->setPosition(Vector3(100,100,300));
mCamera_2->lookAt(Vector3(-100,-100,-300));
mCamera_2->setNearClipDistance(5);
}
createViewports():
void BaseApplication::createViewports(void)
{
// 主窗口
Viewport* vp_1 = mWindow->addViewport( mCamera_1 );
vp_1->setBackgroundColour( ColourValue(0,0,0) );
mCamera_1->setAspectRatio(
Real( vp_1->getActualWidth() ) / Real( vp_1->getActualHeight() ) );
// 畫中畫
Viewport* vp_2 = mWindow->addViewport( mCamera_2, 1, 0.7, 0.05, 0.25, 0.25 );
vp_2->setBackgroundColour( ColourValue(0,0,0) );
vp_2->setOverlaysEnabled(false);
mCamera_2->setAspectRatio(
Real( vp_2->getActualWidth() ) / Real(vp_2->getActualHeight() ) );
}
{
// 主窗口
Viewport* vp_1 = mWindow->addViewport( mCamera_1 );
vp_1->setBackgroundColour( ColourValue(0,0,0) );
mCamera_1->setAspectRatio(
Real( vp_1->getActualWidth() ) / Real( vp_1->getActualHeight() ) );
// 畫中畫
Viewport* vp_2 = mWindow->addViewport( mCamera_2, 1, 0.7, 0.05, 0.25, 0.25 );
vp_2->setBackgroundColour( ColourValue(0,0,0) );
vp_2->setOverlaysEnabled(false);
mCamera_2->setAspectRatio(
Real( vp_2->getActualWidth() ) / Real(vp_2->getActualHeight() ) );
}
在addViewport中我們控制畫中畫視口在主窗口中的位置和大小(注意這里是0~1的取值范圍,類似于貼圖坐標(biāo))
這樣就實(shí)現(xiàn)了下圖所示效果的一半了。
是不是很酷?如果進(jìn)一步設(shè)計(jì)成,當(dāng)觸發(fā)某一事件時(shí)將畫中畫窗口動(dòng)態(tài)的彈出,那就更酷了!有興趣的可以試一試:P
如圖所示,我另外還利用了CEGUI給畫中畫窗口加了個(gè)邊框,并且?guī)Я艘粋€(gè)combobox用來控制更多攝像機(jī)之間的切換,CEGUI是用腳本來定義界面的,實(shí)現(xiàn)也比較簡單。有關(guān)CEGUI部分的介紹,在ogre wiki上有更詳細(xì)的教程。
#end
posted on 2007-05-22 10:59 hitmaen 閱讀(762) 評(píng)論(2) 編輯 收藏 引用 所屬分類: Ogre
評(píng)論
# re: [ 試驗(yàn) ] 用Ogre實(shí)現(xiàn)畫中畫 [ 截圖 ] 2007-05-22 16:14 萬連文
鷹眼,小地圖?? 回復(fù) 更多評(píng)論
# re: [ 試驗(yàn) ] 用Ogre實(shí)現(xiàn)畫中畫 [ 截圖 ] 2007-05-22 19:05 hitmaen
@萬連文鷹眼是什么?不是指小地圖,玩一玩跑跑卡丁車就明白我說的畫中畫是什么了 回復(fù) 更多評(píng)論