没有用过cegui0.7.7以前的版本,所以不是很清楚它之前的版本是怎么初始化的,这里只是说一下bootstrapSystem的这种方式。
cegui作为一个ui框架,它的底层是直接采用低级图形渲染API实现的(d3d或opengl),它的大致思路是这样的。1.通过配置的方式加载样式和资源。2.在渲染的时候调用底层渲染API。3.针对自己定义的控件实现了一套事件机制,用这套机制相应事件。图形界面相关的永远都是怎么显示怎么交互之类的问题。
在cegui0.7.7版本配合ogre的时候,初始化很简单,只需要调用CEGUI::OgreRenderer::bootstrapSystem();方法就行了。挺好用的也不要参数,但是不好理解,尤其是它是怎么获取ogre相关的对象来渲染自己的,都没有体现出来,为此简单的看了一下这个方法相关的代码。
bootstrapSystem:
OgreRenderer& OgreRenderer::bootstrapSystem()
{
if (System::getSingletonPtr())
CEGUI_THROW(InvalidRequestException("OgreRenderer::bootstrapSystem: "
"CEGUI::System object is already initialised."));
OgreRenderer& renderer = create();
OgreResourceProvider& rp = createOgreResourceProvider();
OgreImageCodec& ic = createOgreImageCodec();
System::create(renderer, &rp, static_cast<XMLParser*>(0), &ic);
return renderer;
}
这个方法有两个比较重要地方,创建了一个OgreRenderer对象和一个System对象。其中OgreRenderer对象用来渲染所有界面上的元素。System是cegui的根与ogre的root类型,说到这里必须说一下的是,ogre的代码写的真心烂,什么都放在头文件里,我还以为这个是行业规范呢,看了cegui才找到了回归标准的感觉。
1.OgreRenderer:
OgreRenderer::OgreRenderer() :
d_pimpl(new OgreRenderer_impl())
{
checkOgreInitialised();
// get auto created window
Ogre::RenderWindow* rwnd = d_pimpl->d_ogreRoot->getAutoCreatedWindow();
if (!rwnd)
CEGUI_THROW(RendererException(
"Ogre was not initialised to automatically create a window, you "
"should therefore be explicitly specifying a Ogre::RenderTarget in "
"the OgreRenderer::create function."));
constructor_impl(*rwnd);
}
OgreRenderer_impl() :d_displayDPI(96, 96),d_maxTextureSize(2048),
d_ogreRoot(Ogre::Root::getSingletonPtr()),d_previousVP(0),
d_activeBlendMode(BM_INVALID),d_makeFrameControlCalls(true)
{}
1. 这里需要关注的第一个是d_pimpl对象,它是一个结构体,里面是一些常用对象,其中一个成员是ogreRoot。这个地方默认对其进行初始化d_pimpl(new OgreRenderer_impl(),从下面的OgreRenderer_impl构造可以看出,默认对ogreRoot进行获取了。Ogre::Root::getSingletonPtr() 这表示在对OgreRenderer初始化前必须先new出root。
2. getAutoCreatedWindow 是获取RenderWindow而不是重新new,所以在此之前也必须new出RenderWindow。
3.最后看看constructor_impl这个方法,构造的实现名字取的真不俗,其实主要是对d_pimpl结构体的填充。
constructor_impl :
void OgreRenderer::constructor_impl(Ogre::RenderTarget& target)
{
d_pimpl->d_renderSystem = d_pimpl->d_ogreRoot->getRenderSystem();
d_pimpl->d_displaySize.d_width = target.getWidth();
d_pimpl->d_displaySize.d_height = target.getHeight();
// create default target & rendering root (surface) that uses it
d_pimpl->d_defaultTarget =
new OgreWindowTarget(*this, *d_pimpl->d_renderSystem, target);
d_pimpl->d_defaultRoot =
new RenderingRoot(*d_pimpl->d_defaultTarget);
// hook into the rendering process
d_pimpl->d_ogreRoot->addFrameListener(&S_frameListener);
}
能从ogreRoot获取的坚决不自己new,反正OgreRenderer的初始化就这么些东西了。渲染对象的根也是在这个时候添加的,我们自己new出来的组件都是挂接在这个根上的。渲染对象的关系虽然是个tree但是是以list的形势存储的,父在前子在后,所以查询当前鼠标选中的组件的时候,都是从后面向前面查找的,因为子比父的优先级高。如果要实现点击后子和其父都要进行响应,做法应该是子响应后继续向前找下一个选中的渲染对象。
2.System :
System 的构造看起来比OgreRenderer的更复杂,但它只是履行了它作为这个cegui的入口的责任,大量的创建和初始化。System 的构造看起来比较长,里面主要涉及两个内容:
1.Config_xmlHandler:这个对象里面封装着各种xml配置,在System 构造里会加载这些配置。
2.createSingletons和addStandardWindowFactories的调用。
createSingletons:
void System::createSingletons()
{
// cause creation of other singleton objects
new ImagesetManager();
new FontManager();
new WindowFactoryManager();
new WindowManager();
new SchemeManager();
new MouseCursor();
new GlobalEventSet();
new AnimationManager();
new WidgetLookManager();
new WindowRendererManager();
new RenderEffectManager();
}
addStandardWindowFactories:
void System::addStandardWindowFactories()
{
// Add factories for types all base elements
WindowFactoryManager::addFactory< TplWindowFactory<GUISheet> >();
WindowFactoryManager::addFactory< TplWindowFactory<DragContainer> >();
WindowFactoryManager::addFactory< TplWindowFactory<ScrolledContainer> >();
WindowFactoryManager::addFactory< TplWindowFactory<ClippedContainer> >();
WindowFactoryManager::addFactory< TplWindowFactory<Checkbox> >();
WindowFactoryManager::addFactory< TplWindowFactory<PushButton> >();
WindowFactoryManager::addFactory< TplWindowFactory<RadioButton> >();
WindowFactoryManager::addFactory< TplWindowFactory<Combobox> >();
WindowFactoryManager::addFactory< TplWindowFactory<ComboDropList> >();
WindowFactoryManager::addFactory< TplWindowFactory<Editbox> >();
WindowFactoryManager::addFactory< TplWindowFactory<FrameWindow> >();
WindowFactoryManager::addFactory< TplWindowFactory<ItemEntry> >();
WindowFactoryManager::addFactory< TplWindowFactory<Listbox> >();
WindowFactoryManager::addFactory< TplWindowFactory<ListHeader> >();
WindowFactoryManager::addFactory< TplWindowFactory<ListHeaderSegment> >();
WindowFactoryManager::addFactory< TplWindowFactory<Menubar> >();
WindowFactoryManager::addFactory< TplWindowFactory<PopupMenu> >();
WindowFactoryManager::addFactory< TplWindowFactory<MenuItem> >();
WindowFactoryManager::addFactory< TplWindowFactory<MultiColumnList> >();
WindowFactoryManager::addFactory< TplWindowFactory<MultiLineEditbox> >();
WindowFactoryManager::addFactory< TplWindowFactory<ProgressBar> >();
WindowFactoryManager::addFactory< TplWindowFactory<ScrollablePane> >();
WindowFactoryManager::addFactory< TplWindowFactory<Scrollbar> >();
WindowFactoryManager::addFactory< TplWindowFactory<Slider> >();
WindowFactoryManager::addFactory< TplWindowFactory<Spinner> >();
WindowFactoryManager::addFactory< TplWindowFactory<TabButton> >();
WindowFactoryManager::addFactory< TplWindowFactory<TabControl> >();
WindowFactoryManager::addFactory< TplWindowFactory<Thumb> >();
WindowFactoryManager::addFactory< TplWindowFactory<Titlebar> >();
WindowFactoryManager::addFactory< TplWindowFactory<Tooltip> >();
WindowFactoryManager::addFactory< TplWindowFactory<ItemListbox> >();
WindowFactoryManager::addFactory< TplWindowFactory<GroupBox> >();
WindowFactoryManager::addFactory< TplWindowFactory<Tree> >();
WindowFactoryManager::addFactory< TplWindowFactory<HorizontalLayoutContainer> >();
WindowFactoryManager::addFactory< TplWindowFactory<VerticalLayoutContainer> >();
WindowFactoryManager::addFactory< TplWindowFactory<GridLayoutContainer> >();
}
System 作为cegui的入口,初始化的时候为我们new出了所需要使用的所有对象,这些对象都是以单例的形势存在的,这也是为什么初始化的时候没有赋值给某个引用。当然了,这里的单例模式没有java里面实现的严格,严格意义上讲,为保证单例必须使构造私有化。
总结:一般一个开源的框架,为了使用者的方便,会对初始化部分进行统一的内部处理,以简化使用者的使用。这样的结果是我们很难理解它到底做了些什么,所以在使用前有必要点进去看一下。整个cegui的初始化过程,强调了两个东西。
OgreRenderer :它集中的处理了界面的渲染,使用者不需要自己关注界面元素是如何渲染的,你只需要为界面上的组件设置相应的样式,然后把样式涉及到的资源加载到资源管理器中即可。
System :它管理了cegui里面的所有管理对象包括OgreRenderer ,在构造的时候会对xml配置进行加载,获取初始化的参数。
此文,尽管不涉及细节,但是对cegui整体的了解还是有所帮助的。
分享到:
相关推荐
介绍手机测试的!手机软件测试概述!想了解测试的下载吧!
引言 1.元数据管理视图 2ClearCase元数据管理 3总结上一篇介绍了ClearCase远程客户端(CCRC)对ClearQuest集成的支持与交付/同步。本篇继续介绍ClearCase远程客户端对元数据的管理功能。 引言ClearCase为了满足...
本文将这些应用也分为三块进行详述: Single-Agent Multi-Agent Human-Agent Collaboration 第5章讲的是LLM-based Agent Society。这块的目标在于探究agent如何认识环境,以及如何与其他agent进行复杂的社会性交互...
matlab将代码放大动态缩放 这是该论文的MATLAB代码,将出现在《实验生物学杂志》上:使用自由落体动态缩放模型估算下沉速度:Kong虫作为测试用例,作者是Matthew Walker,JörgU. Hammel,Fabian ...
详述: (1)创建一张最简单的百度地图; (2)管理地图的生命周期,具体请参看代码部分的相关注释; ------------------------------------------------------------------------------------- 二、 Demo名称:多...
选题详述: (1)三种参与角色:客人、系统管理人员、服务及收银台人员 (2)客人功能需求:订桌、点(退)菜、结账。 (3)系统管理员功能需求:菜单及价格维护(含折扣)、用户建立及授权、统计报表生成打印。 (4...
AAR品牌详述:因为我们公司从成立之初,主营是服装面料这块。公司在经过一段时期经营和积淀,并随着市场及电子商务的不断变化与发展,同时为了调整公司经营深度和扩大公司发展广度,公司做了相应的分析和讨论,决定...
详述VOIP基础详述VOIP基础详述VOIP基础详述VOIP基础详述VOIP基础
详述:单片机启动后通过按键设置电机运行速度。红外对管检测当前白线位置,并计算偏差,输送给舵机,控制舵机转向,并沿着白线行走,编码器通过单片机进行计数并测速,实现速度闭环控制,达到恒速运行。LCD屏幕...
百度地图demo(有28种类型demo) 百度地图Android SDK v4.5.2 Sample共有28个Demo,每个Demo的说明...详述: (1)介绍了如何在Fragment框架下添加一个地图地图控件; ------------------------------------------------
有色金属:钴复盘:详述2015年以来钴价走势来龙去脉.pdf
UIScrollView中图片放大后不居中,或居中后移动有偏差解决办法 详述:http://blog.sina.com.cn/s/blog_6ae8b50d0100yret.html
资源详述: 第一:您必须安装vs2010版本,否则将打不开 第二:有相关c++知识 vc编程技巧 功能: 第一:能够获取网卡各种信息 第二:能够将网卡的多个IP一同获取
锂复盘:详述2015年以来锂价走势来龙去脉.pdf
Nand_Flash详述,读写时序及工作原理介绍,对开发有帮助
大数据必学Java基础(二十七):详述main方法和了解可变参数
本篇文章算是对郭霖前辈的一篇文章的详述: 一方面是笔者自己尝试从demo中理解了一下自定义view,另一方面是笔者希望通过更详细的注释已经解说,能帮助新手更容易地理解自定义view的使用。
使用c++实现hill密码的加密解密以及破译,代码可即时运行。 代码详述:代码有两个文件,第一个文件用于加密解密,第二个文件用于破译,均可由用户即时输入,交互性好。
本章主要介绍了华为云计算解决方案中运维功能,并从系统管理员及VDC管理员角度描述了各自的运维工作内容 精选-云计算运维详述全文共44页,当前为第1页。 学完本课程后,您将能够: 了解华为云计算的运维技术 了解...
----------------------- 日志服务器的搭建详述全文共6页,当前为第1页。 日志服务器的搭建详述全文共6页,当前为第2页。 日志服务器的搭建详述全文共6页,当前为第3页。 日志服务器的搭建详述全文共6页,当前为第4...