CEGUI教程 - 图文
更新时间:2023-12-17 12:48:01 阅读量: 教育文库 文档下载
- cegui视频教程推荐度:
- 相关推荐
一 :
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
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
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. 三: 1. 在CEGUI中使用layout文件(3) 2. 打开任意一个layout文件,可见其为一个树形结构,父子窗体 的组织结构比较清晰。 3. 5. 7. 9. window1\ 10. 11. 13. 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程序。注意:如果你使用 //mem probs without this next one #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*)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 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”文件夹下。 现在将程序中下列代码段注释掉 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编程的乐趣:)
正在阅读:
CEGUI教程 - 图文12-17
感恩父亲文章02-21
泡绿豆作文600字06-20
《将草炼成油》阅读答案04-15
法规干部试用期满转正述职报告02-25
教育哲学期末复习题09-13
区金融服务中心上半年开展精准帮扶工作部署07-30
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 图文
- 教程
- CEGUI
- 电机轴径对照表
- 运营商移动数据网络底层分光数据共享探讨
- 2009年职称英语考试模拟冲刺题及参考答案一(理工类A)
- 2019年整理--公安分局副书记科学发展观心得体会
- XX公司企业管理调研报告
- 房地产开发企业税收疑难问题
- 住宅楼施工组织设计
- 射频产品项目可行性研究报告(技术工艺+设备选型+财务概算+厂区规划)方案设计
- 基础与结构工程施工质量监理实施细则
- 责任医生家庭签约式服务协议书
- 药分复习题
- 2012年江苏省公务员考试行测真题(B卷)完整+答案+解析
- 人教部编版(五四学制)六年级上册历史第2课原始农耕生活练习
- 高一政治上教学工作总结
- 湖北省投资、消费与经济增长的协整分析
- 怎样利用二次吸引挽回出轨的丈夫
- 四川省2018学年七年级英语第一次月考试题 人教新目标版 精品 - 图文
- 创新管理模式,关爱留守儿童(留守儿童管理工作汇报材料) - 图文
- Zh107(碾压式土石坝及砌石坝工程单元工程质量评定表)
- 异面直线所成角简单练习