Ogre 1.7 这个版本比以前有了很多的变化.其中之一就是在Ogre官方不再包含CEGUI的组件.但是尽管没有使用CEGUI,在官方的demo中仍然可以看见有gui的功能,那么Ogre又是怎么实现的呢?

根据官网的说明,新的gui系统使用的是一个叫"tray"的系统.这个系统的主要代码在SdkTray.h这个文件之中.sdktray使用的Ogre overlay来实现gui,并且Ogre 1.7比以前版本似乎也多了一些gui相关的组件.这大概预示,Ogre即将开发自己的gui组件,而cegui也许将被抛弃.

不管未来如何,研究下sdktray还是很有意义的一件事情.使用overlay来实现gui,最大的特点在于可以灵活利用Ogre强大的material系统,实现很多不可思议的效果.比起使用cegui来,减少了学习周期.但是比较遗憾的是,目前Ogre 1.7的sdktray还不能作为一个完整的gui组件,

有些功能还很不完善.

现在来研究以下sdktray.h文件的源代码.

首先是2个enum;

ButtonState就如同其名字一样,指的是鼠标按下 悬浮以及释放的情况下的gui对应3种状态.不过一般的说,这3种状态所有gui应该都具备.

接下来是一个sdkTrayListener的基类,从接口来看,应该是实现gui对应的功能.包括点击 选择 移动等等.

Widget是所有窗口组件的基类.一个Widget包含一个OverlayElement,和一个sdktraylistener,分别实现外观和对应的事件响应.这个基类还包括几个static的工具函数.

nukeOverlayElement()的作用是删除掉OverlayElement(包括子element),

isCursorOver ()用来判断鼠标是否悬浮在gui的上方.需要注意的是这个函数判定包括了边框的判断.并且仅仅实现了矩形的判断.这个大概是因为目前所有的OverlayElment都是矩形的缘故.

cursorOffset()获取鼠标离OverlayElement的中心有多少像素远.

getCaptionWidth()用来获取一个textAreaOverlayElement中的caption的长度.caption应该指的是textAreaOverlayElment保存的文本.

fitCaptionToArea()这个函数用来对具体的caption实现简单的格式化.,包括空格的长度以及根据gui长度实现裁剪.但是这个函数没有实现string太长时候的自动换行处理.

接下来的4个virtual函数是回调函数, 用来实现鼠标对应事件响应处理.有意思的是这里没有keyboard对应的callback 这大概意味着目前的sdktray还没有实现响应键盘的功能.

接下的是一个继承自Widget的Button类.如同Ogre许多的部件,Ogre注释中说明,要求使用sdkmanager来创建具体的button.在button的构造函数中可以看到widget的OverlayElement 是使用OverlayManager::createOverlayElementFromTemplate()函数创建的.这个函数的参数是硬编码.这意味着如果我们要使用自己定义的外观,需要更改button的源代码.也许copy一个多出2个参数的构造函数是个不错的选择.button使用了一个有限状态机来实现了基类的4个callback.注意_cursorRelease()中调用了listener的buttonHit()函数,说明button响应点击的逻辑判断在鼠标释放的时候,并且没有对鼠标按下进行逻辑事件的处理.这也是sdktray不够完善的地方.

TextBox继承自Widget,注释说明是"Scrollable Text box",这个类实现了string超出gui宽度时候的换行处理.并且实现了一个下拉条.

为了实现这些功能,这个类包含了一个显示标题的borderPanel,包含标题的textArea,包含caption的textarea,2个实现下拉条效果的Borderpanel和panel.TextBox的构造函数主要就是读取各个子OverlayElement并设置对应的的属性.同button一样,许多属性的值都是硬编码.

最后构造函数调用了一个refitContents的子函数.这个函数的功能是根据新设置的字体属性调用setText()重新排列文本.要复用的话,setText()是很好用的一个对外接口,这个函数设置需要显示的文本,并且将文本自动换行.

setTextAlignment()实现文本对齐,

appentText()实现字体追加.如果要自己实现打字输入,这个函数估计会有很大用途.但是这个函数每次都调用setText(),每次都对所有string重新计算位置,用来实现输入的话应该不是很有效率.

setScrollPercentage()根据下拉的百分比来设置显示的字体.函数调用了filterLines(),这个子函数的功能是决定下拉的时候,哪些行的字体应该被显示.

_cursorPressed()响应了对下拉条点击的处理.需要注意的是 函数使用基类cursorOffset()来进行范围判定,当鼠标在设定的范围内的时候,下拉条才开始响应对应的事件.从demo来看,下拉条是一个圆形,我估计这个圆形的半径是9像素,所以函数中判断使用的数值是81(9的平方).

SelectMenu实现了下拉菜单的功能.getItems(),setItems(),clearItems(),是对所有下拉的组操作,addItem(),removeItem(),selectitem(),getSelectedItem()实现子操作.其中selectItem调用了listener的itemSelected()函数.

label大概是最简单的一个组件.需要注意的这个label在鼠标pressed的时候调用了listener的labelHit()函数.

separator没有响应任何逻辑事件和鼠标事件.也许是用来显示一些把什么东西分开的东西.

slider实现基本的滑块功能.这个用来实现在一定范围内值的选取.setRange() 确定值的上下限,getvalue() setValue()获取设置value.注意value的类型是Real.从setValue()函数实现来看,设置的是滑块的left,也就是说slider类 只能实现横向的滑块移动.

paramsPanel的功能是显示一个基于string类型的<key,value>.从实现上看,没有响应逻辑,也没有响应基本的鼠标事件,他的唯一功能就是显示key的value.程序中可以使用setvalue()来改变key对应的值.

checkBox 选择框.类似于单选框.一个checkBox框对应一个条目.有多个条目要实现多个checkBox.toggle()是一个对外接口,这个函数调用了listener的checkBoxToggled()函数.

DecorWidget 注释说明是用来实现用户自己的widget.这个DecorWidget什么都不做...如果要实现自己的widget,自己写一个继承自widget的类大概比较简明.

ProgressBar 进度条.包含3个部分,标题,正在读取的内容,以及显示进度用的显示条.显示条使用了2个overlayelement,其中一个根据百分比改变宽度,从而实现进度条效果.进度条没有响应任何事件.

sdkTrayManager是widget的管理器.不过看上去为了实现示例的轮盘效果这个manager多了许多的额外功能.如果不是使用示例的那个轮盘的话,很多功能似乎可以去掉.

构造函数中sdktrayManager实现了4个显示层.backdrop trays priority 以及 cursor 层.zorder依次从低到高.这里可以看出sdktrymanager是如何显示鼠标的.在一个单独的overlay层中使用一个overlayElement跟踪鼠标的位置,并实现对应显示.priority层的用途是显示一个dialogShade的OverlayElement,这个看上去是个对话框.但是dialogShade不是一个widget.不明白为什么不单独把这个功能分离出来,要整合到manager中去.接下来的代码设置了tray层.应该对应的是sample demo中对应的那个轮盘gui.出于复用的目的,不讨论tray相关的内容.

几个静态的工具函数:Ogre::Ray screneToscrene()和Ogre::Vector2 screneToScrene(),实现2D坐标和基于相机视口的3D射线之间的互换.refreshCursor()这个函数实现鼠标的更新,并且更新是基于ois unbuffered模式.我个人认为与鼠标有关的都应该独立出来作为一个类.getCursorRay()是screentoScreen()的再封装.接下来是各种widget对应的create函数.需要注意的是create函数将一个自己的mListener成员赋予了widget.这意味着响应事件的逻辑可以集中到manager的listener中,而不需要针对每个widget都写一个listener.

showFrameStates() 这个函数的功能替代了以前debugOverlay的功能.showLoadingBar()显示一个资源读取进度的进度条.showOKDialog() 显示一个有OK button的对话框.showYesNodialog()显示一个有yes no的对话框.这些功能也许都应该独立出来作为一个工具类.

frameRedneringQueued()响应了每帧循环.主要功能是清除不需要的widget以及更新framestates.

injectMouseDown() injectMouseUp() injectMouseMove()处理鼠标事件.overlay zorder 在前的overlayElement先获得处理.

总的来说,各种widget复用程度还是很高的,但是如果需要改变他们的显示的话,需要更改构造函数.sdkmanager的功能比较杂乱,如果需要实现自己的gui系统,应该将一些功能分拆出来.

Ogre 1.7 SDKTRAY 初探相关推荐

  1. 【Ogre编程入门与进阶】第十七章 Ogre3D 和CEGUI 的结合

    17.1 UI库 Ogre中提供给我们的二维处理能力还不足以方便我们构建出一套完美的UI界面,而目前很多成熟的GUI库都可以很好的整合到Ogre3D中,这样很大程度上节省了我们定制UI界面的时间,每一 ...

  2. 网游UI解决方案的选择(作者 鸣·铭)

    网游UI解决方案的选择作者 鸣·铭 转载请注明出自http://www.mobilegamebase.com 由于新项目动工,UI方面需要确定方向,所以最近纠结于各种解决方案的选择.以下是对各方案的比 ...

  3. 网游UI解决方案的选择

    网游UI解决方案的选择 作者 鸣·铭  转载请注明出自http://www.mobilegamebase.com 由于新项目动工,UI方面需要确定方向,所以最近纠结于各种解决方案的选择.以下是对各方案 ...

  4. 网游UI解决方案的选择(转)

    网游UI解决方案的选择作者 鸣·铭  转载请注明出自http://www.mobilegamebase.com 由于新项目动工,UI方面需要确定方向,所以最近纠结于各种解决方案的选择.以下是对各方案的 ...

  5. 网游UI解决方案的选择(CEGUI/MYGUI/Hikari/Scaleform/...)

    网游UI解决方案的选择 作者 鸣·铭 转载请注明出自http://www.mobilegamebase.com 由于新项目动工,UI方面需要确定方向,所以最近纠结于各种解决方案的选择.以下是对各方案的 ...

  6. 2021年大数据Flink(九):Flink原理初探

    Flink原理初探 Flink角色分工 在实际生产中,Flink 都是以集群在运行,在运行的过程中包含了两类进程. JobManager: 它扮演的是集群管理者的角色,负责调度任务.协调 checkp ...

  7. 从壹开始微服务 [ DDD ] 之一 ║ D3模式设计初探 与 我的计划书

    缘起 哈喽大家周四好!又是开心的一天,时间过的真快,我们的 <从壹开始 .net core 2.1 + vue 2.5 >前后端分离系列共 34 篇已经完结了,当然以后肯定还会有更新和修改 ...

  8. OGRE 2.1 Windows 编译

    版权所有,转载请注明链接 OGRE 2.1 Windows 编译 环境: Windows 7 64Bit Visual Studio 2012 OGRE 2.1 CMake 2.8.12.1 OGRE ...

  9. 经典算法研究系列:二、Dijkstra 算法初探

    经典算法研究系列:二.Dijkstra 算法初探  July   二零一一年一月 ====================== 本文主要参考:算法导论 第二版.维基百科. 写的不好之处,还望见谅. 本 ...

最新文章

  1. R语言对dataframe进行行数据筛选(row selection)多种方案:使用R原生方法、data.table、dplyr等方案
  2. php mysql 时间差_PHP中计算时间差的方法
  3. Scala 中将方法、函数、函数式编程和面向对象编程关系分析图
  4. 文件“D:\file.txt”正由另一进程使用,因此该进程无法访问该文件。
  5. 抽丝剥茧,深入剖析 Python 如何实现变量交换!
  6. redis学习之——redis.conf配置(基本)文件学习
  7. fopen如何保存西里尔文文件名_如何下载微信视频号的视频?
  8. Zookeeper数据一致性原理
  9. 计算机软件和理论学什么,武汉大学计算机软件与理论考研科目有哪些?
  10. [Ext JS]Grid的列过滤
  11. 利用whistle调试移动端页面
  12. hadoop提交作业到云端问题解决
  13. 攻击者利用7号信令(SS7)中的漏洞从德国银行偷取钱财
  14. 怎样将Sublime Text 设置成中文版(完整教程)
  15. 随机森林树的特点--摘抄笔记
  16. 用 Python 编辑 PDF 文件
  17. Going Deeper with Contextual CNN for Hyperspectral Image Classification
  18. [TCP灵魂之问]TCP 的拥塞控制、慢启动、慢启动阈值、拥塞避免、快速重传和快速恢复
  19. (转)ICO泡沫:8万本金赚套房子和宝马 几分钟十几万没了
  20. 微信网页版web通讯全解析(最新,持续更新,附源码)

热门文章

  1. Python Imaging Library: ImageTk Module(图像Tkinter模块)
  2. Servlet的单例模式
  3. vue solt 属性浅析
  4. 「镁客·请讲」小i机器人朱频频:会话AI将成为主流人机交流方式,积累和深度学习是关键...
  5. Java Web之基于注解的Spring MVC环境配置
  6. Android开发的四大组件
  7. Linux CTRL+ALT+DELETE
  8. [原]Unity3D深入浅出 - 新版粒子系统 (Shuriken)
  9. sqlserver2008秘钥
  10. 新年新服务: MVP 播客上线