mygui与hge结合
最近对mygui有点兴趣,据说ogre官方都力挺她而抛弃cegui了,不说她界面做的多炫,也不管她多方便,更不管她提供了好多例子和编辑工具,就冲着这小三的精神,咱也不能小看了她不是。google搜了一下mygui,结果还挺多,不过内容大多只是简单介绍一下她怎么用,没有实质性的好东西。加上由于她是出自俄国人之手,文档除了没有,就是俄文,然而我也没有找到传说中的教程。
对于ogre、dx、opengl的渲染支持,mygui已经提供,不再赘述。我想以后可能在2d项目中应用mygui,以前做2d的时候用hge比较多,遂打算将hge和mygui结合起来,网上又是一次大搜索,几乎翻遍了,没找到解决方案。然后果断自己动手。下图是一个修改时作为测试的mygui的官方demo,效果是相当不错。
首先,以官方提供的directXPlatform改起(对于mygui的编译可以参考本博其他博文)。目的是使用hge渲染mygui,原则是不修改mygui和hge的源码,只做中间件。主要修改的地方就那么几点,也没有网上说的工作量大的那么邪乎,遇到的问题几乎都是小问题。hge用的是v1.8.1(dx8),mygui是v3.0.1。
1.将dxplatform中所有的mpD3DDevice和设备指针的参数全换成mpHGE待用;
2.修改VertexBuffer。这一步也挺重要。mygui是通过dx直接分配顶点缓冲内存,因为我不想修改hge代码,也不愿意破坏hge的高效率,这里我把分配显存直接改成了分配所需大小的内存,然后在内存上操作,渲染的时候再利用hge的RenderQuad等接口拷贝到显存渲染,这样的效率可能会慢一些。但是想想myguiDirectXPlatform的处理方法,也不是太好,没有像hge那样做渲染批次的优化。这暂时是我想到的最快的方法了(编码最快。。。),有更好的方法一定要分享出来。(我已经把directxplatform改成hgeplatform了)
bool HGEVertexBuffer::create() { mpBuffer = new Vertex[mNeedVertexCount]; memset(mpBuffer,0,mNeedVertexCount*sizeof(Vertex)); if (mpBuffer) return true; return false; }
3.修改RenderManager把dx相关的操作都去掉。这里注意一个接口isFormatSupported,这个需要返回false,如果返回true的话字体会有问题,等改好了你可以试试效果。然后最重要的两个修改的地方就是设置视角矩阵和投影矩阵以及渲染方式的改变。把begin()里的代码全部去掉,修改setViewSize接口:
mInfo.maximumDepth = 0.5f; mInfo.hOffset = -0.5f; mInfo.vOffset = -0.5f; mInfo.aspectCoef = float(mViewSize.width) / float(mViewSize.height); mInfo.pixScaleX = 0.5f; mInfo.pixScaleY = -0.5f;
注意这几个参数,为了使mygui里对坐标的处理与hge的视角对应好,需要这样做。这也是使hge能正确渲染mygui的最重要一点。
然后修改doRender接口:
HGETexture* dxTex = static_cast<HGETexture*>(_texture); HGEVertexBuffer* dxVB = static_cast<HGEVertexBuffer*>(_buffer); MyGUI::Vertex* pVertex = dxVB->lock(); hgeTriple Triple; Triple.tex = dxTex->getHGETexture(); Triple.blend = BLEND_DEFAULT; for (size_t t = 0;t<_count;t+=3) { memcpy(Triple.v, pVertex+t, 3*sizeof(Vertex)); mpHGE->Gfx_RenderTriple(&Triple); }
这里其实也好理解,mygui使用的quad是6顶点格式的,而hge是4顶点,这里使用hge的渲染三角形接口来画,也算是偷懒了。
4.修改Texture,很简单,直接把hge支持的纹理加载、锁定、解锁、销毁等等接口全部换过来;
5.修改BaseManager。这里就简单了,就是我们熟悉的hge的参数设置、创建、启动、销毁等等了。我这里为了测试方便又偷懒了,使用了一个全局变量Base::BaseManager* basemanager来保存当前的BaseManager指针,以便从全局的hgeFrame向BaseManager::HgeFrameFunc过渡。你可以想到更好的办法。
6.修改好了。
在修改这个东西的过程中,遇到了好多细节上的问题,主要还是技术不精,还好遇到困难坚持做了下来,做完才发现其实也没有特别复杂的东西。
总结一下,这个hge和mygui的结合,还没到能商业应用的级别,因为很多问题都没处理。比如:设备丢失与恢复处理,RTTTexture的处理,和其他很多细节问题等。另外对于帧速我还没有测试,等测试完成会发结果上来。
由于技术水平有限,文中难免出现错误,望网友不吝指教。
PS:2011.9.6 代码已经整理完毕,有不少问题,欢迎提出。下载地址:执行程序+代码: http://dl.dbank.com/c07aqq6ao2