最新的OGRE把例子都做为插件,在SampleBrowser中浏览。

那个浏览的界面做的真是好看,操作起来也不错,于是想把他的那个Sample的缩略图显示拿出来,以后做为游戏关卡的选择界面。

 

主要用的还是OGRE中的Overlay。

声明:

        // ui function
void SetupUI();
void SetupLevelMenu();
void UpdateUI(double timeSinceLastFrame);

// for ui
OgreBites::SelectMenu* m_pMenu;
std::vector<Ogre::OverlayContainer*> m_Thumbs; // sample thumbnails
Ogre::StringVector m_SampleNames;
Ogre::Real m_CarouselPlace;

 

定义:

    m_SampleNames.push_back("thumb_bezier");
m_SampleNames.push_back("thumb_bsp");
m_SampleNames.push_back("thumb_bump");
m_SampleNames.push_back("thumb_camtrack");
m_SampleNames.push_back("thumb_cel");



 

void CMenuState::SetupLevelMenu()
{
// create template material for sample thumbnails
Ogre::MaterialPtr thumbMat = Ogre::MaterialManager::getSingleton().create("SampleThumbnail", "Essential");
thumbMat->getTechnique(0)->getPass(0)->createTextureUnitState();
Ogre::MaterialPtr templateMat = Ogre::MaterialManager::getSingleton().getByName("SampleThumbnail");

Ogre::StringVector::iterator itr;

for (itr = m_SampleNames.begin(); itr != m_SampleNames.end(); itr++)
{

Ogre::String name = "SampleThumb" + Ogre::StringConverter::toString(m_Thumbs.size() + 1);

// clone a new material for sample thumbnail
Ogre::MaterialPtr newMat = templateMat->clone(name);

Ogre::TextureUnitState* tus = newMat->getTechnique(0)->getPass(0)->getTextureUnitState(0);
if (Ogre::ResourceGroupManager::getSingleton().resourceExists("Essential", *itr + ".png"))
tus->setTextureName(*itr + ".png");
else
tus->setTextureName("thumb_error.png");

Ogre::BorderPanelOverlayElement* bp = (Ogre::BorderPanelOverlayElement*)
Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate("SdkTrays/Picture", "BorderPanel", (*itr));

//Ogre::ResourceGroupManager::getSingletonPtr()->loadResourceGroup("Essential");

bp->setHorizontalAlignment(Ogre::GHA_RIGHT);
bp->setVerticalAlignment(Ogre::GVA_CENTER);
bp->setMaterialName(name);
COgreFramework::getSingletonPtr()->m_pTrayMgr->getTraysLayer()->add2D(bp);

m_Thumbs.push_back(bp);
}
}

 

更新:

void CMenuState::UpdateUI(double timeSinceLastFrame)
{
// makes the carousel spin smoothly toward its right position
Ogre::Real carouselOffset = m_pMenu->getSelectionIndex() - m_CarouselPlace;
if ((carouselOffset <= 0.001) && (carouselOffset >= -0.001)) m_CarouselPlace = m_pMenu->getSelectionIndex();
else m_CarouselPlace += carouselOffset * Ogre::Math::Clamp<Ogre::Real>(timeSinceLastFrame * 0.015, -1.0, 1.0);

for (int i = 0; i < (int)m_Thumbs.size(); i++)
{
Ogre::Real thumbOffset = m_CarouselPlace - i;
Ogre::Real phase = (thumbOffset / 2.0) - 2.8;

if (thumbOffset < -5 || thumbOffset > 4) // prevent thumbnails from wrapping around in a circle
{
m_Thumbs[i]->hide();
continue;
}
else m_Thumbs[i]->show();

Ogre::Real left = Ogre::Math::Cos(phase) * 200.0;
Ogre::Real top = Ogre::Math::Sin(phase) * 200.0;
Ogre::Real scale = 1.0 / Ogre::Math::Pow((Ogre::Math::Abs(thumbOffset) + 1.0), 0.75);

Ogre::BorderPanelOverlayElement* frame =
(Ogre::BorderPanelOverlayElement*)m_Thumbs[i]->getChildIterator().getNext();

m_Thumbs[i]->setDimensions(128.0 * scale, 96.0 * scale);
frame->setDimensions(m_Thumbs[i]->getWidth() + 16.0, m_Thumbs[i]->getHeight() + 16.0);
m_Thumbs[i]->setPosition((int)(left - 80.0 - (m_Thumbs[i]->getWidth() / 2.0)),
(int)(top - 5.0 - (m_Thumbs[i]->getHeight() / 2.0)));

if (i == m_pMenu->getSelectionIndex()) frame->setBorderMaterialName("SdkTrays/Frame/Over");
else frame->setBorderMaterialName("SdkTrays/Frame");
}
}


最后加上鼠标的滑轮操作:

bool CMenuState::mouseMoved(const OIS::MouseEvent &evt)
{

OIS::MouseState state = evt.state;
OIS::MouseEvent orientedEvt((OIS::Object*)evt.device, state);

if (orientedEvt.state.Z.rel != 0 && m_pMenu->getNumItems() != 0)
{
int newIndex = m_pMenu->getSelectionIndex() - orientedEvt.state.Z.rel / Ogre::Math::Abs(orientedEvt.state.Z.rel);
m_pMenu->selectItem(Ogre::Math::Clamp<int>(newIndex, 0, m_pMenu->getNumItems() - 1));
}

if (COgreFramework::getSingletonPtr()->m_pTrayMgr->injectMouseMove(evt))
return true;

return true;
}

 

效果图: