在OSG下创建第一个CEGUI窗口

30 篇文章 1 订阅

最近在做OSG与CEGUI结合的工作,感觉CEGUI在制作绚丽的GUI方面有着很强的优势,这也是很多游戏开发者对其推崇的原因吧。下面将介绍一下如何在OSG中创建自己的第一个CEGUI窗口,有兴趣的朋友可以多多指教。

    首先,在工程开始添加所需的头文件(这个就不用我啰嗦了吧)。构建一个用于绘制CEGUI窗口的类CEGUIDraw继承自osg::Drawable。代码如下:

class CEGUIDraw : public osg::Drawable
{
public:
CEGUIDraw();
CEGUIDraw(const CEGUIDraw& drawable,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
Drawable(drawable,copyop) {}

META_Object(osg,CEGUIDraw);

//初始话CEGUI,添加所需要的资源以及设定相关的属性
void InitCEGUI();
//这个函数在基类Drawable里是一个纯虚函数,实现OpenGL渲染时必须重写
void drawImplementation(osg::RenderInfo& renderInfo) const;

protected:
//析构函数。在结束时释放资源
virtual ~CEGUIDraw();
unsigned int m_activeContextID;
};

     CEGUIDraw类成员函数的实现:

CEGUIDraw::CEGUIDraw()
{
setSupportsDisplayList(false);
new CEGUI::System(new CEGUI::OpenGLRenderer(0));
m_activeContextID = 0;
}

void CEGUIDraw::drawImplementation(osg::RenderInfo& renderInfo) const
{
osg::State& state = *renderInfo.getState();

if (state.getContextID()!=m_activeContextID) return;

glPushAttrib(GL_ALL_ATTRIB_BITS);

state.disableAllVertexArrays();

//在每帧渲染后调用
CEGUI::System::getSingleton().renderGUI();

glPopAttrib();

state.checkGLErrors("CEGUIDraw::drawImplementation");
}

void CEGUIDraw::InitCEGUI()
{
CEGUI::SchemeManager::getSingleton().loadScheme("TaharezLook.scheme");

CEGUI::WindowManager& winmgr = CEGUI::WindowManager::getSingleton();
CEGUI::Window *myroot = winmgr.createWindow("DefaultWindow","root");
//DefaultWindow是不可见的,相当于一个画布
CEGUI::System::getSingleton().setGUISheet(myroot);

CEGUI::FrameWindow *frameWnd = (CEGUI::FrameWindow*)(winmgr.createWindow("TaharezLook/FrameWindow","TestWindow"));
myroot->addChildWindow(frameWnd);
frameWnd->setPosition(CEGUI::UVector2( CEGUI::UDim( 0.25f, 0 ), CEGUI::UDim( 0.25f, 0 ) ));
frameWnd->setSize(CEGUI::UVector2( CEGUI::UDim( 0.25f, 0 ), CEGUI::UDim( 0.25f, 0 ) ) );
frameWnd->setText("TestWindow");

}

CEGUIDraw::~CEGUIDraw()
{
// delete CEGUI??
}

    下面是主函数的实现部分:

void main()
{

//创建OSG场景的根结点
osg::ref_ptr<osg::Group> rootNode = new osg::Group;
osgViewer::Viewer viewer;

//此句比较关键。因为CEGUI只支持单线程,所以必须在构建CEGUIDraw类的对象之前调用此句,不然就

//会出现OpenGL资源正在使用中,无法获取的问题。
viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);

//下面两句代码也很关键。其作用是初始化OpenGL环境,如果没有这两句运行后界面将无法显示
viewer.realize();
viewer.getCamera()->getGraphicsContext()->makeCurrent();

osg::Geode *ceguiGeode = new osg::Geode;
CEGUIDraw *cd = new CEGUIDraw();
cd->InitCEGUI();
ceguiGeode->addDrawable(cd);

osg::Node *model = osgDB::readNodeFile("glider.osg");
rootNode->addChild(ceguiGeode);
rootNode->addChild(model);
viewer.setSceneData(rootNode.get());
viewer.run();
}

    总结,这里仅仅是用C++硬编码的方式实现了在OSG里创建一个简单的CEGUI窗口,其实还是用通过XML布局文件实现窗口的创建,这样更加灵活。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值