天天看点

ogre与CEGUI结合

注意需要4个动态链接库,才行,一个是ceguibase,一个是渲染器CEGUIFalagardWRBase.dll,一个是CEGUIExpatParser.dll

,还有一个就是ogreRender:CEGUIOgreRenderer.dll,否则第一个函数bootstrapSystem就会有异常,

这四个动态链接库中:渲染器和xml分析器ExpatParser是动态加载的。

还有要设置mainsheet才行,不然窗口显示不出来:mGUISystem->setGUISheet(MainSheet);

可以用多个layout来组织程序用到的界面,用其中一个layout作为gui系统的mainsheet。其他的layout要显示出来,首先要作为

mainsheet的子窗口才行:MainSheet->addChildWindow(wnd);

关于光标:Ogre的BaseApplication类里面有个OgreBites::SdkTrayManager,这个东西是做界面的,里面有各种控件,还可以设置光标,这个光标是用overlay做的

在ois的鼠标各种事件监听函数里面,以及各种帧监听器里面调用SdkTrayManager相应的事件函数,驱动这个东西工作。

要把SdkTrayManager的光标隐藏。

CEGUI也有自己的光标,这两个东西都是界面,放一起用,理论上不好,只用一个就好了。

可以事先把需要用的ImageSet和Font写入到scheme文件里面,这样在解析scheme文件的时候自动解析这些文件

从而不用自己在代码里面手动创建这些东西了。

CEGUI::WindowManager::getSingleton().loadWindowLayout函数返回的是layout里面的最后一个窗口。

当cegui找不到对应的imageset和image的时候,不会报错,只是不显示。

当设置了窗口属性AlwaysOnTop的时候,鼠标点击其他窗口是无效的,当前窗口相当于模态对话框窗口了。

当系统设置了缺省字体的时候:若窗口某个地方需要用到其他字体而这个字体没有定义的时候,就会使用缺省字体。

layout窗口的大小不是你看到的大小,而是layout里面最顶级父窗口的大小,有的时候这个大小是看不到的,

这个顶级父窗口可能覆盖了其他的窗口,但由于他是透明的,所有有的时候你点击其他的窗口老是切换不过去就是这个原因

CEGUI中窗口的Zorder:

cegui中没有什么属性是指定窗口的z order的,我发现,窗口的Zorder跟窗口的创建顺序有关,最后创建的窗口在最前面。

但有几个函数控制zorder的:setRiseOnClickEnabled(true),鼠标一点击窗口就到最顶层。

setZOrderingEnabled()表示zorder是否可以改变。这个函数影响:moveToFront, moveToBack, moveInFront and moveBehind

cegui的初始化代码:

mGUIRenderer = &CEGUI::OgreRenderer::bootstrapSystem();

mGUISystem = CEGUI::System::getSingletonPtr();

CEGUI::SchemeManager::getSingleton().create((CEGUI::utf8*)"WindowsLook.scheme");

CEGUI::SchemeManager::getSingleton().create((CEGUI::utf8*)"VanillaSkin.scheme");

//mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");

//CEGUI::MouseCursor::getSingleton().setImage((CEGUI::utf8*)"TaharezLook",(CEGUI::utf8*)"MouseMoveCursor"); 

//CEGUI::System::getSingleton().setDefaultTooltip( (CEGUI::utf8*)"TaharezLook/Tooltip" );

CEGUI::FontManager::getSingleton().create("SimHei-12.font");

mGUISystem->setDefaultFont("SimHei-12");

CEGUI::Window *MainSheet=CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)"EntranceWnd.layout");

mGUISystem->setGUISheet(MainSheet);

mEntranceWnd = CEGUI::WindowManager::getSingleton().getWindow("EntranceWnd");

mEntranceWnd->hide();

mEntranceButton = static_cast<CEGUI::PushButton*>(CEGUI::WindowManager::getSingleton().getWindow("Button/Entrance"));

mEntranceButton->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&TutorialApplication::entranceButtonHandle, this));

一个鼠标键转换函数:

CEGUI::MouseButton convertButton(OIS::MouseButtonID buttonID)

{

switch (buttonID)

{

case OIS::MB_Left:

return CEGUI::LeftButton;

case OIS::MB_Right:

return CEGUI::RightButton;

case OIS::MB_Middle:

return CEGUI::MiddleButton;

default:

return CEGUI::LeftButton;

}

}

每一帧都要调用:

CEGUI::System::getSingleton().injectTimePulse(evt.timeSinceLastFrame);

还有鼠标和键盘处理:

bool TutorialApplication::mouseMoved( const OIS::MouseEvent &arg )

{

BaseApplication::mouseMoved(arg);

mGUISystem->injectMouseMove( arg.state.X.rel, arg.state.Y.rel );

mGUISystem->injectMouseWheelChange(arg.state.Z.rel);

return true;

}

bool TutorialApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )

{

BaseApplication::mousePressed(arg,id);

mGUISystem->injectMouseButtonDown(convertButton(id));

return true;

}

bool TutorialApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )

{

BaseApplication::mouseReleased(arg,id);

mGUISystem->injectMouseButtonUp(convertButton(id));

return true;

}

bool TutorialApplication::keyPressed(const OIS::KeyEvent &arg )

{

BaseApplication::keyPressed(arg);

mGUISystem->injectKeyDown(arg.key);

mGUISystem->injectChar(arg.text);

return true;

}

bool TutorialApplication::keyReleased( const OIS::KeyEvent &arg )

{

if(arg.key == OIS::KC_X)

{

std::cout<<mCamera->getPosition();

std::cout<<std::endl;

}

mGUISystem->injectKeyUp(arg.key);

return BaseApplication::keyReleased(arg);

}

CEGUI的事件处理函数:

bool eventHandler(const CEGUI::EventArgs& e)

在窗口事件处理函数里面,可以对参数const CEGUI::EventArgs& e,进行转换,如果事先知道是哪种窗口的事件:

((RadioButton*)((const WindowEventArgs&)e).window),通过这样可以得到触发这个事件的窗口指针。

根据一个图片文件创建Imageset,这样创建的Imageset里面只有一个image,名字为full_image。

CEGUI::ImagesetManager::getSingleton().createFromImageFile("bkdddd", "bkdddd.tga");

wnd->setProperty("Image", "set: bkdddd image:full_image");