CEGUI教程 - 图文

更新时间:2023-12-17 12:48:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

一 :

1. 你的第一个CEGUI程序

2. 强烈建议仔细研究CEGUISample程序!因为那里介绍了它的一些基本用法,其实最后在游戏当中出现的,也就是这些例子的变化而已。 3. 这里我会引导你写一个第一个自己的简单的CEGUI程序,它使用CEGUISampleHelper提供的框架,使用OpenGL渲染。

4. 这是在CEGUI自己给的Sample程序基础上简化、简化、再简化得出的,目的是让大家对CEGUI程序有一个简单明了的认识,其实就是这么简单。里面只定义了一个背景,一个静态文本,写着“Hello!CEGUI”。 5. 具体的,有几块重要的东西。有一些包含在框架里了,如下: 6. DefaultResourceProvider,这个是CEGUI的一个全局的东西,可以在任何地方操作它的指针,但是一般只需要在一开始操作它。 7. 在CEGuiOpenGLBaseApplication当中,你可以看见下面这样的代码,这就是在使用DefaultResourceProvider的指针在设置资源的路径,你可以毫不客气地复制粘贴到你的工程里 8. CEGUI::DefaultResourceProvider* rp =

static_cast

9. (CEGUI::System::getSingleton().getResourceProvider()); 10.

11. rp->setResourceGroupDirectory(\\

12. rp->setResourceGroupDirectory(\\

13. rp->setResourceGroupDirectory(\\

14. rp->setResourceGroupDirectory(\\

15. rp->setResourceGroupDirectory(\\

16. rp->setResourceGroupDirectory(\\ 17. 下面是整个的代码: 18. #ifndef _TDemo0_h_ 19. #define _TDemo0_h_ 20.

21. #include \ 22. #include \ 23.

24. // 例子类

25. class TDemo0Sample : public CEGuiSample 26. ...{

27. public:

28. // 用于实现初始化的方法 29. bool initialiseSample(); 30.

31. // 关闭

32. void cleanupSample(void); 33. };

34. #endif //_TDemo0_h_ 35. 36. 37. 38. 39.

40. #include \ 41. #include \

42. #include \ 43. #include 44.

45. /**//************************************************************************* 46. 程序入口

47. *************************************************************************/

48. int main(int argc, char *argv[]) 49. ...{

50. TDemo0Sample app; 51. return app.run(); 52. } 53.

54. /**//************************************************************************* 55. 实现初始化方法

56. *************************************************************************/

57. bool TDemo0Sample::initialiseSample() 58. ...{

59. using namespace CEGUI; 60.

61. // 得到窗口管理器

62. WindowManager& winMgr = WindowManager::getSingleton();

63. // 装载资源,只说一下scheme就行,其它的system自己去调

64. SchemeManager::getSingleton().loadScheme(\k.scheme\

65. // 鼠标指针很特殊,但是其实是一样的用法

66. System::getSingleton().setDefaultMouseCursor(\ook\ 67. // 字体

68. FontManager::getSingleton().createFont(\-10.font\ 69.

70. // 这里创建了一个window。第一个参数指定了这个window的类型,第二个参数是名字。 71. Window* background =

winMgr.createWindow(\\ 72.

73. // 设置位置和大小

74. background->setPosition(UVector2(cegui_reldim(0), cegui_reldim( 0)));

75. background->setSize(UVector2(cegui_reldim(1), cegui_reldim( 1))); 76.

77. // 这就要把刚才那个background用作最底层的窗口了

78. System::getSingleton().setGUISheet(background); 79.

80. // 其实这个在这里没啥用,我认为,只是多了一层窗口。在任何UI系统当中所有的窗口都是一样的。 81. Window* sheet =

winMgr.createWindow(\ 82.

83. // 叠加上

84. background->addChildWindow(sheet); 85.

86. // 又创建了一个窗口,这回是一个静态的文本 87. Window* st =

winMgr.createWindow(\\

88. sheet->addChildWindow(st);

89. st->setPosition(UVector2(cegui_reldim(0.45f), cegui_reldim( 0.23f)));

90. st->setSize(UVector2(cegui_reldim(0.15f), cegui_reldim( 0.05f)));

91. st->setText(\ 92.

93. return true;

94. } 95.

96. /**//************************************************************************* 97.

98. *************************************************************************/

99. void TDemo0Sample::cleanupSample() 100. 101. 102. 103. 104.

...{

// 啥事也不做 }

好了,现在可以新建一个工程,模仿其它例子的工程结构,然后用

这个代码,编译,就OK了。 105.

这就是(或者几乎是一个)最简单的CEGUI程序,其实就是这么简

单。

二:

1. 在CEGUI中使用layout文件(1)

2. CEGUI支持两种方式的资源使用,一种就是在前文可见的直接在c++文件当中创建窗体,使用窗体;另一种方式就是在layout文件当中定制窗体。从理论上讲,两种方式都能达到相同的目的。

3. 在不使用layout文件时,CEGUI是不太方便的,因为要定位控件,常常得修改文件当中的参数,如果在c++文件当中修改,每次都编译,很恶心(尤其是在有编辑器的情况下,使用c++就不能使用了)。 4. 所以如果你要使用CEGUI,对layout文件的使用和编辑都是必修课。 5. 下面这个就是一个简单的使用layout文件的例子,作的仅仅是把文件读进来、显示在窗口里了。 6.

7. #include \ 8. #include \

9. #include \ 10.

11. #include 12.

13. int main(int argc, char *argv[]) 14. ...{

15. TDemo1 app; 16. return app.run(); 17. } 18.

19. /**//************************************************************************* 20.

21. *************************************************************************/

22. bool TDemo1::initialiseSample() 23. ...{

24. using namespace CEGUI; 25.

26. // 窗体管理器

27. WindowManager& winMgr = WindowManager::getSingleton(); 28.

29. // 载入资源

30. SchemeManager::getSingleton().loadScheme(\k.scheme\

31. System::getSingleton().setDefaultMouseCursor(\ook\

32. FontManager::getSingleton().createFont(\-10.font\

33. // 在此载入layout文件

34. // 这个就是要在实际当中经常使用的 35. Window* sheet =

winMgr.loadWindowLayout(\ 36. System::getSingleton().setGUISheet(sheet);

37.

38. return true; 39. } 40.

41. /**//************************************************************************* 42.

43. *************************************************************************/

44. void TDemo1::cleanupSample() 45. ...{

46. // 啥也不做 47. } 48. 49.

50. TDemo1.layout 51. 52. 53.

54.

56.

57.

58.

59.

60.

62.

63. 66. 67.

三:

1. 在CEGUI中使用layout文件(3)

2. 打开任意一个layout文件,可见其为一个树形结构,父子窗体

的组织结构比较清晰。

3.

5. 6.

7.

9.

window1\ 10.

11. 12.

13. 14.

15. 16. 17.

18. 由于使用的是TinyXML作的xml解析器,其是基于DOM的,

所以正合适。 19.

20. 注意文件当中的Property tag,这个是layout的重点,通过

设定这个东西,CEGUI就活起来了。

21.

23. 如果想在游戏中使用你编辑的layout文件,那么就不是单个文

件这么简单了。

24. 由于CEGUI当中的窗体名称是一个全局的向量,所以不能有同

名的窗体,这样,命名规则就成了一个问题,当游戏制作到了大规模的UI制作阶段,这个问题尤为明显。 25. 我的经验是如下的规则: 26.

27. 1. 规则1 Layout文件命名

28. layout文件以场景形式组织,每个layout文件对应一个场景下

的UI,文件名为场景的英文名称,首字母大写,如SampleScene.layout。

29. 2. 规则2 顶级控件命名&设定

30. layout文件内部使用Root_场景英文名的defaultWindow作

为根窗口(顶级窗口),如示例场景的UI使用

Root_SampleScence作为根窗口。顶级窗口大小为整个显示屏幕大小。

31. 3. 规则3 次级控件命名

32. Root窗口下一级UI控件使用 场景英文名+控件实际用途方式

命名,如示例场景下的背景图片命名为SampleSceneBackground。 33. 4. 规则4 其它控件命名

34. 次级以下控件使用 上一级控件名/控件自身控件名 的方式进

行命名,如示例场景下的退出按钮命名为 SampleSceneBackground/Quit。 35. 5. 规则 5 UI控件命名

36. UI控件命名规则为 UI控件名含义+控件类型(可选),如设置

按钮可命名为SampleSceneBackground/Settings 或者SampleSceneBackground/SettingsButton。 37.

38. 这样一来,只要文件名不同,就保证了UI控件没有重名了。

四:

论坛上有好多朋友困惑于CEGUI无法显示和输入中文的问题。输入问题暂且不说,起码显示中文应该不难吧。我研究了两天,其间不知用了多少遍Google,跑到CEGUI和OGRE的官方网站和论坛找了很久,都没有太多的帮助。也看了打工仔写的相关文档,但是好像需要修改源代码,然后重新编译。难道CEGUI的最新版0.5.1还不支持中文吗?!最后只好自己一点一点摸索。谁知竟然真的被我摸到了,呵呵。下面我就说一说,怎样用CEGUI显示中文。

本教程只是对中文显示做出一些说明,对于其他问题请参阅其他相关文档。本教程使

用OgreSDK中的Demo_Ocean为例。

第一步,我们需要准备一个中文字体,我选用的是Window XP系统自带的simhei.ttf(这个字体在系统文件夹WINDOWS\\Fonts中可以找到)。我们需要把它复制到Ogre安装目录中media下的fonts目录中(例如:C:\\OgreSDK\\media\\fonts),这个fonts目录中存放有例子中需要用到的字体文件。

第二步,我们需要准备一个simhei-12.font文件,这个文件可以用记事本编辑,然后保存到Ogre安装目录中media下的gui目录中(例如:C:\\OgreSDK\\media\\gui),其内容如下:

注意:切记不要写段,我最初在网上看到有朋友给出的教程有这个段的内容,说是将你的程序中需要用的字加在这个段中。但是,据我实验得出的结论是,如果加入这个段,会导致创建字体时发生异常,根据CEGUI.log中的提示,是“Glyphs is unknown”。 第三步,检查一下resources.cfg,看看上面用到的fonts和gui两个目录的路径是否正确,如果你是使用SDK的话应该没问题。

第四步,修改OceanDemoCegui.config,将原来的BlueHighway-12修改为SimHei-12。注意:大小写不要写错。

第五步,修改TaharezLookSkin.scheme,在????之前,增加我们的中文字体说明

注意:大小写不要写错。

第六步,打开OceanDemo.cpp,我们要将左下角的状态统计说明的Current FPS,

Avarage FPS,Worst FPS,Best FPS,Triangle Count这几项改成当前帧数:,平均帧数:,最差帧数:,最优帧数:,三角形数:。找到OceanDemo_FrameListener::updateStats,看到了吧。我们将原先的

static CEGUI::String currFps = \static CEGUI::String avgFps = \static CEGUI::String bestFps = \static CEGUI::String worstFps = \static CEGUI::String tris = \ 修改为

static CEGUI::String currFps = (CEGUI::utf8*)Ogre::UTFString(L\当前帧率:\

static CEGUI::String avgFps = (CEGUI::utf8*)Ogre::UTFString(L\平均帧率:\

static CEGUI::String bestFps = (CEGUI::utf8*)Ogre::UTFString(L\最优帧率:\

static CEGUI::String worstFps = (CEGUI::utf8*)Ogre::UTFString(L\最差帧率:\

static CEGUI::String tris = (CEGUI::utf8*)Ogre::UTFString(L\三角形数:\

最后要注意的是,凡是见到汉字的地方都要保存为Unicode(UTF-8)格式。我用VS2005在 文件-高级保存选项 中选择Unicode(UTF-8 带签名)。 好了,都做完了。编译链接一下看看吧。

PS:用layout文件预制gui时可以直接把Text 的value设置为汉字如:

同样也要保存为utf-8。

见到论坛上有好多朋友困惑于CEGUI无法显示和输入中文的问题。输入问题暂且不说,起

码显示中文应该不难吧。我研究了两天,其间不知用了多少遍Google,跑到CEGUI和OGRE的官方网站和论坛找了很久,都没有太多的帮助。也看了打工仔写的相关文档,但是好像需要修改源代码,然后重新编译。难道CEGUI的最新版0.5.1还不支持中文吗?!最后只好自己一点一点摸索。谁知竟然真的被我摸到了,呵呵。下面我就说一说,怎样用CEGUI显示中文。

本教程只是对中文显示做出一些说明,对于其他问题请参阅其他相关文档。本教程使用OgreSDK中的Demo_Ocean为例。

第一步,我们需要准备一个中文字体,我选用的是Window XP系统自带的simhei.ttf(这个字体在系统文件夹WINDOWS\\Fonts中可以找到)。我们需要把它复制到Ogre安装目录中media下的fonts目录中(例如:C:\\OgreSDK\\media\\fonts),这个fonts目录中存放有例子中需要用到的字体文件。

第二步,我们需要准备一个simhei-12.font文件,这个文件可以用记事本编辑,然后保存到Ogre安装目录中media下的gui目录中(例如:C:\\OgreSDK\\media\\gui),其内容如下:

注意:切记不要写段,我最初在网上看到有朋友给出的教程有这个段的内容,说是将你的程序中需要用的字加在这个段中。但是,据我实验得出的结论是,如果加入这个段,会导致创建字体时发生异常,根据CEGUI.log中的提示,是“Glyphs is unknown”。

第三步,检查一下resources.cfg,看看上面用到的fonts和gui两个目录的路径是否正确,如果你是使用SDK的话应该没问题。

第四步,修改OceanDemoCegui.config,将原来的BlueHighway-12修改为

SimHei-12。注意:大小写不要写错。 第五步,修改TaharezLookSkin.scheme,在

之前,增加我们的中文字体说明

注意:大小写不要写错。

第六步,打开OceanDemo.cpp,我们要将左下角的状态统计说明的Current FPS,Avarage FPS,Worst FPS,Best FPS,Triangle Count这几项改成当前帧数:,平均帧数:,最差帧数:,最优帧数:,三角形数:。找到OceanDemo_FrameListener::updateStats,看到了吧。我们将原先的

static CEGUI::String currFps = \static CEGUI::String avgFps = \static CEGUI::String bestFps = \static CEGUI::String worstFps = \static CEGUI::String tris = \ 修改为

static CEGUI::String currFps = (CEGUI::utf8*)Ogre::UTFString(L\当前帧率:

\

static CEGUI::String avgFps = (CEGUI::utf8*)Ogre::UTFString(L\平均帧率:\

static CEGUI::String bestFps = (CEGUI::utf8*)Ogre::UTFString(L\最优帧率:\

static CEGUI::String worstFps = (CEGUI::utf8*)Ogre::UTFString(L\最差帧率:\

static CEGUI::String tris = (CEGUI::utf8*)Ogre::UTFString(L\三角形数:\

最后要注意的是,凡是见到汉字的地方都要保存为Unicode(UTF-8)格式。我用VS2005在 文件-高级保存选项 中选择Unicode(UTF-8 带签名)。 好了,都做完了。编译链接一下看看吧。

PS:用layout文件预制gui时可以直接把Text 的value设置为汉字如: 同样也要保存为utf-8。

五:

工程设置

下面的适用于下载源代码的用户:

添加include文件夹: $(OGRE_HOME)\\Dependencies\\include, $(OGRE_HOME)\\Dependencies\\include\\CEGUI 添加lib库路

径: $(OGRE_HOME)\\OgreMain\\Dependencies\\Lib\\Debug

确信已经链接 'CEGUIBase' 和 'OgreGUIRender' 库,也就是说将下面一行添加进你的Makefile文件或g++命令行:

-L/usr/local/lib -lCEGUIBase -lCEGUIOgreRenderer 下面的适用于SDK的用户:

添加include文件夹:$(OGRE_HOME)\\include\\CEGUI 确信已经在debug配置的中添加 'CEGUIBase_d.lib' 和 'OgreGUIRenderer_d.lib' 库( 'CEGUIBase.lib' 和

'OgreGUIRenderer.lib' 在release配置中)。在Visual C++中添加依赖,依次点击:项目 -> 属性 -> 配置属性 -> 链接。

CEGUIRender源程序现在是从Ogre CVS下载代码中的一部分,一个示例工程,因此你必须将包含OgreGUIRenderer头文件和lib文件的文件夹路径添加到属性配置中。

另外,下面两个目录是必需的。尽管你在你的安装路径中的文件夹找不到。将其作为约定它就会起作用: 添加Include文件夹:

$(OGRE_HOME)\\Samples\\Common\\CEGUIRenderer\\include 添加 Lib 路

径: $(OGRE_HOME)\\Samples\\Common\\CEGUIRenderer\\lib

介绍

Crazy Eddies GUI系统是一个为不具备或缺乏用户界面制作功能的图形API或引擎提供免费用户界面支持的开源的库。这个使用c++编写的库是针对那些想制作优秀的游戏却又没有GUI(图形用户界面)子系统的专业游戏开发者。 开始

首先,你需要架构(skeleton)代码来创建具有CEGUI组件的Ogre程序。注意:如果你使用,你必须在之前添加#define NOMINMAX。

//mem probs without this next one #include #include #include #include

#include #include #include #include \

#include \//regular mem handler

#include

#include \

class GuiFrameListener : public ExampleFrameListener { private:

CEGUI::Renderer* mGUIRenderer; public:

GuiFrameListener(RenderWindow* win, Camera* cam, CEGUI::Renderer* renderer)

: ExampleFrameListener(win, cam, false, false), mGUIRenderer(renderer) { } };

仅仅是一个不做任何动作的空帧监听器,但在你按下“Esc”之前会一直循环。 class TutorialApplication : public ExampleApplication { private:

CEGUI::OgreCEGUIRenderer* mGUIRenderer; CEGUI::System* mGUISystem; CEGUI::Window* mEditorGuiSheet;

这些是包含所有CEGUI数据的数据成员。我喜欢显示的调用CEGUI成员,一但你开始对Ogre成员添加调用,这将会明确的说明它们是来自CEGUI。

public:

TutorialApplication() : mGUIRenderer(0), mGUISystem(0), mEditorGuiSheet(0) { }

~TutorialApplication() {

if(mEditorGuiSheet) {

CEGUI::WindowManager::getSingleton().destroyWindow(mEditorGuiSheet); }

if(mGUISystem) {

delete mGUISystem; mGUISystem = 0; }

if(mGUIRenderer) {

delete mGUIRenderer;

mGUIRenderer = 0; } }

下面是你可以设置任意Ogre场景的地方,使用你在前五章教程学到的方法。在这个Ogre场景中,你仍要为其添加一个独立的相机(camera)和视窗(viewport)。 protected:

void createScene(void) {

// Set ambient light

mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); 下面是创建CEGUI日志的地方,一般都设置为Informative模式的。其具有四种模式:Standard, Errors, Informative 和 Insane。 // Set up GUI system

mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr); mGUISystem = new CEGUI::System(mGUIRenderer);

CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);

创建一个新的CEGUI系统,使用“TaharezLook”来设置图(sheme)与鼠标指针,使用“BlueHighway-12”来设置字体。

CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)\

mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)\zLook\

CEGUI::MouseCursor::getSingleton().setImage(\\

mGUISystem->setDefaultFont((CEGUI::utf8*)\2\

mEditorGuiSheet=CEGUI::WindowManager::getSingleton().createWindow((CEGUI::utf8*)\

(CEGUI::utf8*)\ mGUISystem->setGUISheet(mEditorGuiSheet); }

调用自定义的帧监听器,这样我们可以在需要时访问“mGUIRender”。 void createFrameListener(void) {

mFrameListener = new GuiFrameListener(mWindow, mCamera, mGUIRenderer);

mRoot->addFrameListener(mFrameListener); } };

下面是主函数也是程序的主循环,在本教程并不需要你修改这段代码。

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include \

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else

int main(int argc, char **argv) #endif {

// Create application object TutorialApplication app; try { app.go();

} catch( Exception& e ) {

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32

MessageBox( NULL, e.getFullDescription().c_str(), \exception has occured!\MB_TASKMODAL); #else

fprintf(stderr, \occured: %s\\n\#endif

} return 0; }

完成后,编译程序能得到一个空的窗口。请关掉程序,继续我们的学习。注意:如果实际操作中出现问题,你可以在应用程序所在文件夹中找到“CEGUI.log”文件分析查找错误

CEGUI是如何工作的

本质上CEGUI是通过向窗口添加第二个场景,这个场景是在Ogre的基本渲染队列完成后才渲染的。这个场景仅仅是由一系列3D矩形对象组成的。(也就是两个多边形沿着其边压制到一起)。渲染矩阵是为消除矩形的突兀与歪斜而根据他们的位置建立的。使用这些矩形,添加材质和响应就构成了用户界面(GUI)。一般情况下这是很不错的,因为一个3D的用户界面将会自动的缩放其元素来适应屏幕,并且使用硬件材质过滤。其将会比C++标准的2D用户界面更加快速和漂亮。

“So in one sentence: CEGUI renders a 2D gui using 3D methods and hardware so you don't have to.”——zeroskill 添加退出按钮

首先,我们需要为应用程序添加下面的头文件。本例中是“Push Button”

#include 我们要在场景底部添加退出按钮。 CEGUI::PushButton* quitButton =

(CEGUI::PushButton*)CEGUI::WindowManager::getSingleton().createWindow

(\(CEGUI::utf8*)\

mEditorGuiSheet->addChildWindow(quitButton); quitButton->setPosition(CEGUI::Point(0.35f, 0.45f)); quitButton->setSize(CEGUI::Size(0.3f, 0.1f)); quitButton->setText(\

完成后执行程序,一个漂亮的按钮将会出现在屏幕中。但请注意,程序此时仍然不做任何事情,因为我们并没有为其添加响应时间。

如果你编译时遇到了setPosition()和setSize()的调用错误:

'CEGUI::Window::setPosition' : cannot convert parameter 1 from 'CEGUI::Vector2' to 'const CEGUI::UVector2 &' 将setPosition()和setSize()所在行分别用下面的代码替换:

quitButton->setPosition(CEGUI::UVector2(cegui_reldim(0.35f), cegui_reldim( 0.45f)) );

quitButton->setSize(CEGUI::UVector2(cegui_reldim(0.35f), cegui_reldim( 0.1f)) ); 响应事件

将下面函数添加到TutorialApplication的public:中 void setupEventHandlers(void) {

CEGUI::WindowManager& wmgr = CEGUI::WindowManager::getSingleton();

wmgr.getWindow((CEGUI::utf8*)\:PushButton::EventClicked, CEGUI::Event::Subscriber

(&TutorialApplication::handleQuit, this)); }

bool handleQuit(const CEGUI::EventArgs& e) {

static_cast(mFrameListener)->requestShutdown();

return true; }

重写 GuiFrameListener 类来响应键盘和鼠标输入

class GuiFrameListener : public ExampleFrameListener, public MouseMotionListener, public MouseListener

{ private:

CEGUI::Renderer* mGUIRenderer; bool mShutdownRequested; public:

// NB using buffered input

GuiFrameListener(RenderWindow* win, Camera* cam, CEGUI::Renderer* renderer)

: ExampleFrameListener(win, cam, true, true), mGUIRenderer(renderer), mShutdownRequested(false) {

mEventProcessor->addMouseMotionListener(this); mEventProcessor->addMouseListener(this); mEventProcessor->addKeyListener(this); }

// Tell the frame listener to exit at the end of the next frame void requestShutdown(void) {

mShutdownRequested = true; }

bool frameEnded(const FrameEvent& evt)

{

if (mShutdownRequested) return false; else

return ExampleFrameListener::frameEnded(evt); }

void mouseMoved (MouseEvent *e) {

CEGUI::System::getSingleton().injectMouseMove( e->getRelX() * mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight()); e->consume(); }

void mouseDragged (MouseEvent *e) {

mouseMoved(e); }

void mousePressed (MouseEvent *e) {

CEGUI::System::getSingleton().injectMouseButtonDown( convertOgreButtonToCegui(e->getButtonID())); e->consume();

}

void mouseReleased (MouseEvent *e) {

CEGUI::System::getSingleton().injectMouseButtonUp( convertOgreButtonToCegui(e->getButtonID())); e->consume(); }

void mouseClicked(MouseEvent* e) {} void mouseEntered(MouseEvent* e) {} void mouseExited(MouseEvent* e) {} void keyPressed(KeyEvent* e) {

if(e->getKey() == KC_ESCAPE) {

mShutdownRequested = true; e->consume(); return; }

CEGUI::System::getSingleton().injectKeyDown(e->getKey()); CEGUI::System::getSingleton().injectChar(e->getKeyChar()); e->consume(); }

void keyReleased(KeyEvent* e) {

CEGUI::System::getSingleton().injectKeyUp(e->getKey()); e->consume(); }

void keyClicked(KeyEvent* e) {

// Do nothing e->consume(); } };

Ogre 1.4.0

如果你使用的是Ogre 1.4.0 你将会要使用OIS。在Ogre3d中使用OIS的更多细节,请参阅使用OIS并且再看一看基础教程5:

class GuiFrameListener : public ExampleFrameListener, public OIS::MouseListener, public OIS::KeyListener { private:

CEGUI::Renderer* mGUIRenderer; bool mShutdownRequested; public:

// NB using buffered input

GuiFrameListener(RenderWindow* win, Camera* cam, CEGUI::Renderer* renderer)

: ExampleFrameListener(win, cam, true, true), mGUIRenderer(renderer), mShutdownRequested(false) {

mMouse->setEventCallback( this ); mKeyboard->setEventCallback( this ); }

// Tell the frame listener to exit at the end of the next frame void requestShutdown(void) {

mShutdownRequested = true; }

bool frameEnded(const FrameEvent& evt) {

if (mShutdownRequested) return false; else

return ExampleFrameListener::frameEnded(evt); }

bool mouseMoved( const OIS::MouseEvent &e ) {

using namespace OIS;

CEGUI::System::getSingleton().injectMouseMove(e.state.X.rel,e.state.Y.rel); return true; }

bool mousePressed (const OIS::MouseEvent &e, OIS::MouseButtonID id) {

CEGUI::System::getSingleton().injectMouseButtonDown(convertOgreButtonToCegui(id)); return true; }

bool mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id ) {

CEGUI::System::getSingleton().injectMouseButtonUp(convertOgreButtonToCegui(id)); return true; }

bool keyPressed( const OIS::KeyEvent &e )

{

if(e.key == OIS::KC_ESCAPE) {

mShutdownRequested = true; return true; }

CEGUI::System::getSingleton().injectKeyDown(e.key); CEGUI::System::getSingleton().injectChar(e.text); return true; }

bool keyReleased( const OIS::KeyEvent &e ) {

CEGUI::System::getSingleton().injectKeyUp(e.key); return true; } };

在include语句后GuiFrameListener声明前添加下面代码

CEGUI::MouseButton convertOgreButtonToCegui(int buttonID) {

switch (buttonID) {

case MouseEvent::BUTTON0_MASK: return CEGUI::LeftButton;

case MouseEvent::BUTTON1_MASK: return CEGUI::RightButton; case MouseEvent::BUTTON2_MASK: return CEGUI::MiddleButton; case MouseEvent::BUTTON3_MASK: return CEGUI::X1Button; default:

return CEGUI::LeftButton; } }

Ogre 1.4.0

CEGUI::MouseButton convertOgreButtonToCegui(int buttonID) {

using namespace OIS; 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; } }

将下面语句添加到创建场景方法(createscene)的末尾。 setupEventHandlers();

现在你可以编译并执行程序了。实现效果是点击按钮后退出。

加载设置(Layout)

CEGUI使用XML格式来加载图形用户界面样式设置。复制下面xml代码到记事本,并将其以“Tutoral Gui.xml”命名另存在“\\media\\gui”文件夹下。

Ogre 1.4.0

现在将程序中下列代码段注释掉 mEditorGuiSheet=

CEGUI::WindowManager::getSingleton().createWindow((CEGUI::utf8*)\ mGUISystem->setGUISheet(mEditorGuiSheet);

CEGUI::PushButton* quitButton =

(CEGUI::PushButton*)CEGUI::WindowManager::getSingleton().createWindow

(\(CEGUI::utf8*)\

mEditorGuiSheet->addChildWindow(quitButton); quitButton->setPosition(CEGUI::Point(0.35f, 0.45f)); quitButton->setSize(CEGUI::Size(0.3f, 0.1f)); quitButton->setText(\在同样位置添加下列代码 mEditorGuiSheet =

CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)\

mGUISystem->setGUISheet(mEditorGuiSheet);

CEGUI::PushButton* quitButton=(CEGUI::PushButton*)CEGUI:: WindowManager::getSingleton().getWindow((CEGUI::utf8*)%uit\

最后一行多余的,因为我们没有在之后使用指针,但是其说明了如何通过加载文件来进行访问。注意:我们在创建xml文件时要根据实际窗口进行设计。 完成后编译并执行,程序在外观上并没有变化。

尝试

?视线相交和选取Ogre mesh—当鼠标没有从GUI元素上移过。 ?定义一个在GUI根菜单上的鼠标点击动作。当你鼠标点击一个不在根窗口中的GUI元素时,它将会响应你的鼠标点击。如果你的鼠标并没有从一个 GUI元素上滑过(也就是说当你的鼠标指针还在我们的3D场景中)则根窗口响应鼠标点击。 ?将鼠标点击转换到世界坐标系和视线相交((Camera::getCamera)到ViewportRay(mouseX, mouseY)) // Start a new ray query

Ogre::Ray cameraRay = root::getSingleton( ).

getCamera( )->getCameraToViewportRay( mouseX, mouseY ); Ogre::RaySceneQuery *raySceneQuery = root::getSingleton( ). getSceneManager( )->createRayQuery( cameraRay ); raySceneQuery->execute( );

Ogre::RaySceneQueryResult result = raySceneQuery->getLastResults( );

Ogre::MovableObject *closestObject = NULL; real closestDistance = LONG_MAX;

std::list< Ogre::RaySceneQueryResultEntry >::iterator rayIterator; for ( rayIterator = result.begin( ); rayIterator != result.end( ); rayIterator++ ) {

if ( ( *rayIterator ).movable->getUserObject( ) != NULL ) {

if ( ( *rayIterator ).distance < closestDistance ) {

closestObject = ( *rayIterator ).movable; closestDistance = ( *rayIterator ).distance; } } }

// No object clicked

if ( closestObject == NULL ) {

clickedObject = NULL; ---- clickedObject is a class scoped variable } else {

clickedObject = static_cast<

object* >( closestObject->getUserObject( ) ); }

raySceneQuery->clearResults( );

root::getSingleton( ).getSceneManager( )->destroyQuery( raySceneQuery )

如何在两个GUI(用户界面)之间转换(使用透明度)

例如:如果你有一个登陆界面,在成功登陆后,进入了你的用户主界面。你将会想在这两个界面间切换。 ?第一步,加载登陆用户界面。 //First loading with this

mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000,mSceneMgr); mGUISystem = new CEGUI::System(mGUIRenderer);

CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);

CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)\

mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)\ok\ CEGUI::Font *f =

CEGUI::FontManager::getSingleton().createFont(\.font\

mGUISystem->setDefaultFont(f); //End \ //Load a XML file mEditorGuiSheet =

CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)\

mGUISystem->setGUISheet(mEditorGuiSheet); 第二步,如果你想删除并重建一个GUI,你需要做到以下: if(mEditorGuiSheet)

CEGUI::WindowManager::getSingleton().destroyWindow(mEditorGuiSheet);

最后一步,加载其他的GUI mEditorGuiSheet =

CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)\

mGUISystem->setGUISheet(mEditorGuiSheet); 重做第二步和最后一步来加载其他GUI。 结论

这个教程为你展示了在Ogre3D下使用CEGUI的一些基本方法,你可以感受下使用CUEGUI编程的乐趣:)

mGUISystem->setGUISheet(mEditorGuiSheet); 第二步,如果你想删除并重建一个GUI,你需要做到以下: if(mEditorGuiSheet)

CEGUI::WindowManager::getSingleton().destroyWindow(mEditorGuiSheet);

最后一步,加载其他的GUI mEditorGuiSheet =

CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)\

mGUISystem->setGUISheet(mEditorGuiSheet); 重做第二步和最后一步来加载其他GUI。 结论

这个教程为你展示了在Ogre3D下使用CEGUI的一些基本方法,你可以感受下使用CUEGUI编程的乐趣:)

本文来源:https://www.bwwdw.com/article/bz25.html

Top