VS2010+OSG3.2+CEGUI0.8.4环境下实现简单的HelloWorld程序
写文章之前必须要先吐槽一下CEGUI的兼容性,好多函数改了名称换了命名空间,以致于花了好长时间查看自带的Demo文件以及帮助文档,不过最终还是搞出来了,现将整个流程编写如下。
1.首先创建工程之前必须先链接OSG以及CEGUI的开发库,根据自身配置路径进行设置,现将本人设置路径贴出来以供参考,如下:
包含目录:
E:\OSG\include
F:\CEGUI\cegui-0.8.4\cegui\include
F:\CEGUI\cegui-0.8.4\dependencies\include
F:\CEGUI\cegui-0.8.4\samples_framework\include
库目录:
E:\OSG\lib
F:\CEGUI\cegui-0.8.4\lib
F:\CEGUI\cegui-0.8.4\dependencies\lib\dynamic
F:\CEGUI\cegui-0.8.4\dependencies\lib\static
附加依赖项:
OpenThreadsd.lib
osgd.lib
osgDBd.lib
osgUtild.lib
osgGAd.lib
osgViewerd.lib
osgTextd.lib
osgWidgetd.lib
CEGUIBase-0_d.lib
CEGUIOpenGLRenderer-0_d.lib
glew.lib
glu.lib
opengl.lib
2.创建CEGUIDrawable,实现对CEGUI的渲染。
#pragma once
#include <osg/Drawable>
#include <osg/RenderInfo>
#include <CEGUI/CEGUI.h>
#include <CEGUI/System.h>
#include <CEGUI/DefaultResourceProvider.h>
#include <CEGUI/RendererModules/OpenGL/GL.h>
#include <CEGUI/RendererModules/OpenGL/GLRenderer.h>
#include <CEGUI/Scheme.h>
#include <CEGUI/SchemeManager.h>
#include <CEGUI/Font.h>
#include <CEGUI/FontManager.h>
#include <CEGUI/Image.h>
#include <CEGUI/ImageManager.h>
#include <CEGUI/Window.h>
#include <CEGUI/WindowManager.h>
#include <CEGUI/WindowRenderer.h>
#include "CEGUIEventCallback.h"
class CEGUIDrawable : public osg::Drawable
{
public:
CEGUIDrawable(void);
~CEGUIDrawable(void);
public:
CEGUIDrawable(const CEGUIDrawable&drawable,const osg::CopyOp ©op=osg::CopyOp::SHALLOW_COPY):Drawable(drawable,copyop){}
META_Object(osg,CEGUIDrawable);
void InitCEGUI(); //初始化CEGUI,添加所需要的资源以及设定相关属性
void drawImplementation(osg::RenderInfo& renderInfo) const;
//这个函数在基类Drawable里是一个纯虚函数,实现OpenGL渲染时必须重写
};
#include "StdAfx.h"
#include "CEGUIDrawable.h"
CEGUIDrawable::CEGUIDrawable(void)
{
setSupportsDisplayList(false);//CEGUI仅支持单线程,必须进行设置才能渲染
CEGUI::OpenGLRenderer& myRenderer =CEGUI::OpenGLRenderer::create();
myRenderer.enableExtraStateSettings(true);//必须进行设置才能让字体显示
setEventCallback(new CEGUIEventCallback);//事件处理函数
CEGUI::System::create(myRenderer);
CEGUI::DefaultResourceProvider* rp = static_cast(CEGUI::System::getSingleton().getResourceProvider());
rp->setResourceGroupDirectory("schemes", "F:\\CEGUI\\cegui-0.8.4\\datafiles\\schemes");
rp->setResourceGroupDirectory("imagesets", "F:\\CEGUI\\cegui-0.8.4\\datafiles\\imagesets");
rp->setResourceGroupDirectory("fonts", "F:\\CEGUI\\cegui-0.8.4\\datafiles\\fonts");
rp->setResourceGroupDirectory("layouts", "F:\\CEGUI\\cegui-0.8.4\\datafiles\\layouts");
rp->setResourceGroupDirectory("looknfeels", "F:\\CEGUI\\cegui-0.8.4\\datafiles\\looknfeel");
rp->setResourceGroupDirectory("lua_scripts", "F:\\CEGUI\\cegui-0.8.4\\datafiles\\lua_scripts");
// This is only really needed if you are using Xerces and need to specify the schemas location
rp->setResourceGroupDirectory("schemas", "F:\\CEGUI\\cegui-0.8.4\\datafiles\\xml_schemas");
CEGUI::ImageManager::setImagesetDefaultResourceGroup("imagesets");
CEGUI::Font::setDefaultResourceGroup("fonts");
CEGUI::Scheme::setDefaultResourceGroup("schemes");
CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
CEGUI::WindowManager::setDefaultResourceGroup("layouts");
CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
parser->setProperty("SchemaDefaultResourceGroup", "schemas");
}
CEGUIDrawable::~CEGUIDrawable(void)
{
}
void CEGUIDrawable::InitCEGUI()
{
using namespace CEGUI;
CEGUI::SchemeManager::getSingleton().createFromFile( "TaharezLook.scheme" );
CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage( "TaharezLook/MouseArrow" );
Font& defaultFont = FontManager::getSingleton().createFromFile("DejaVuSans-10.font");
System::getSingleton().getDefaultGUIContext().setDefaultFont(&defaultFont);
WindowManager& wmgr = WindowManager::getSingleton();
Window* myRoot = (Window* )wmgr.createWindow( "DefaultWindow", "root" );
System::getSingleton().getDefaultGUIContext().setRootWindow( myRoot );
FrameWindow* fWnd = static_cast<FrameWindow* >(wmgr.createWindow( "TaharezLook/FrameWindow", "testWindow" ));
myRoot->addChild( fWnd );
fWnd->setPosition( UVector2(UDim( 0.25f,0.0f),UDim(0.25f,0.0f)));
fWnd->setSize(USize(UDim(0.5f, 0.0f), UDim(0.5f,0.0f)));
fWnd->setText( "Hello World!");
}
void CEGUIDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
{
CEGUI::System::getSingleton().renderAllGUIContexts();
}
3.编写CEGUIEventCallback,实现对CEGUI的事件处理
#pragma once
#include <osgGA/GUIActionAdapter>
#include <osgGA/GUIEventAdapter>
#include <osgGA/GUIEventHandler>
#include <CEGUI/System.h>
#include <CEGUI/GUIContext.h>
class CEGUIEventCallback : public osgGA::GUIEventHandler
{
public:
CEGUIEventCallback();
~CEGUIEventCallback(void);
public:
virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa);
};
#include "StdAfx.h"
#include "CEGUIEventCallback.h"
CEGUIEventCallback::CEGUIEventCallback()
{
}
CEGUIEventCallback::~CEGUIEventCallback(void)
{
}
bool CEGUIEventCallback::handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa)
{
switch(ea.getEventType())
{
case osgGA::GUIEventAdapter::DRAG:
case osgGA::GUIEventAdapter::MOVE:
{
CEGUI::System::getSingleton().getDefaultGUIContext().injectMousePosition(ea.getX(),900-ea.getY());
//CEGUI的坐标系统跟OSG坐标系统是不一样的,如果是全屏的话,CEGUI中的0在OSG中是900(以1440*900为例),所以需要进行调整,以便CEGUI与OSG屏幕一致
return false;
}
case osgGA::GUIEventAdapter::PUSH:
{
CEGUI::System::getSingleton().getDefaultGUIContext().injectMousePosition(ea.getX(),900-ea.getY());
//CEGUI的坐标系统跟OSG坐标系统是不一样的,如果是全屏的话,CEGUI中的0在OSG中是900(以1440*900为例),所以需要进行调整,以便CEGUI与OSG屏幕一致
if (ea.getButton()==osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
{
CEGUI::System::getSingleton().getDefaultGUIContext().injectMouseButtonDown(CEGUI::LeftButton);
}
else
{
}
return false;
}
case osgGA::GUIEventAdapter::RELEASE:
{
CEGUI::System::getSingleton().getDefaultGUIContext().injectMousePosition(ea.getX(),900-ea.getY());
//CEGUI的坐标系统跟OSG坐标系统是不一样的,如果是全屏的话,CEGUI中的0在OSG中是900(以1440*900为例),所以需要进行调整,以便CEGUI与OSG屏幕一致
if (ea.getButton()==osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
{
CEGUI::System::getSingleton().getDefaultGUIContext().injectMouseButtonUp(CEGUI::LeftButton);
}
else
{
}
return false;
}
}
return false;
}
4.编写main函数,实现窗口渲染
#include "stdafx.h"
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include "CEGUIDrawable.h"
int _tmain(int argc, _TCHAR* argv[])
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded); //CEGUI仅支持单线程,必须进行设置
viewer->realize(); //CEGUI仅支持单线程,必须进行设置
viewer->getCamera()->getGraphicsContext()->makeCurrent(); //CEGUI仅支持单线程,必须进行设置
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<CEGUIDrawable> cd = new CEGUIDrawable;
geode->addDrawable(ceguiDrawable);
ceguiDrawable->InitCEGUI();
osg::ref_ptr<osg::Group> group = new osg::Group;
group->addChild(geode);
group->addChild(osgDB::readNodeFile("glider.osg"));
viewer->setSceneData(group);
return viewer->run();
}