OGRE基础教程六.docx
《OGRE基础教程六.docx》由会员分享,可在线阅读,更多相关《OGRE基础教程六.docx(16页珍藏版)》请在冰豆网上搜索。
![OGRE基础教程六.docx](https://file1.bdocx.com/fileroot1/2022-12/30/890dcd25-7afe-4578-a4fb-20add0a30836/890dcd25-7afe-4578-a4fb-20add0a308361.gif)
OGRE基础教程六
教程:
基础教程:
基础教程六
必备知识
本教程是在假设你已经拥有c++编程基础并能够成功建立和编译Ogre程序(如果你设置程序方面还存在问题,请参阅SettingUpAnApplication来获取详细信息)。
本教程建立在之前的初学者教程的基础上,并且假设你已经学习了它们。
工程设置
下面的适用于下载源代码的用户:
添加include文件夹:
$(OGRE_HOME)\Dependencies\include,
$(OGRE_HOME)\Dependencies\include\CEGUI
添加lib库路径:
$(OGRE_HOME)\OgreMain\Dependencies\Lib\Debug
确信已经链接'CEGUIBase'和'OgreGUIRender'库,也就是说将下面一行添加进你的Makefile文件或g++命令行:
-L/usr/local/lib-lCEGUIBase-lCEGUIOgreRenderer
下面的适用于SDK的用户:
添加include文件夹:
$(OGRE_HOME)\include\CEGUI
确信已经在debug配置的中添加'CEGUIBase_d.lib'和'OgreGUIRenderer_d.lib'库('CEGUIBase.lib'和'OgreGUIRenderer.lib'在release配置中)。
在VisualC++中添加依赖,依次点击:
项目->属性->配置属性->链接。
CEGUIRender源程序现在是从OgreCVS下载代码中的一部分,一个示例工程,因此你必须将包含OgreGUIRenderer头文件和lib文件的文件夹路径添加到属性配置中。
另外,下面两个目录是必需的。
尽管你在你的安装路径中的文件夹找不到。
将其作为约定它就会起作用:
添加Include文件夹:
$(OGRE_HOME)\Samples\Common\CEGUIRenderer\include
添加Lib路径:
$(OGRE_HOME)\Samples\Common\CEGUIRenderer\lib
介绍
CrazyEddiesGUI系统是一个为不具备或缺乏用户界面制作功能的图形API或引擎提供免费用户界面支持的开源的库。
这个使用c++编写的库是针对那些想制作优秀的游戏却又没有GUI(图形用户界面)子系统的专业游戏开发者。
开始
首先,你需要架构(skeleton)代码来创建具有CEGUI组件的Ogre程序。
注意:
如果你使用,你必须在之前添加#defineNOMINMAX。
#include
#include
#include
#include
#include
#include
#include"OgreCEGUIRenderer.h"
#include"OgreCEGUIResourceProvider.h"
//regularmemhandler
#include"ExampleApplication.h"
classGuiFrameListener :
publicExampleFrameListener
{
private:
CEGUI:
:
Renderer*mGUIRenderer;
public:
GuiFrameListener(RenderWindow*win,Camera*cam,CEGUI:
:
Renderer*renderer)
:
ExampleFrameListener(win,cam,false,false),
mGUIRenderer(renderer)
{
}
};
仅仅是一个不做任何动作的空帧监听器,但在你按下“Esc”之前会一直循环。
classTutorialApplication :
publicExampleApplication
{
private:
CEGUI:
:
OgreCEGUIRenderer*mGUIRenderer;
CEGUI:
:
System*mGUISystem;
CEGUI:
:
Window*mEditorGuiSheet;
这些是包含所有CEGUI数据的数据成员。
我喜欢显式的调用CEGUI成员,一但你开始对Ogre成员添加调用,这将会明确的说明它们是来自CEGUI。
public:
TutorialApplication()
:
mGUIRenderer(0),
mGUISystem(0),
mEditorGuiSheet(0)
{
}
~TutorialApplication()
{
if(mEditorGuiSheet)
{
CEGUI:
:
WindowManager:
:
getSingleton().destroyWindow(mEditorGuiSheet);
}
if(mGUISystem)
{
deletemGUISystem;
mGUISystem=0;
}
if(mGUIRenderer)
{
deletemGUIRenderer;
mGUIRenderer=0;
}
}
下面是你可以设置任意Ogre场景的地方,使用你在前五章教程学到的方法。
在这个Ogre场景中,你仍要为其添加一个独立的相机(camera)和视窗(viewport)。
protected:
voidcreateScene(void)
{
//Setambientlight
mSceneMgr->setAmbientLight(ColourValue(0.5,0.5,0.5));
下面是创建CEGUI日志的地方,一般都设置为Informative模式的。
其具有四种模式:
Standard,Errors,Informative和Insane。
//SetupGUIsystem
mGUIRenderer=newCEGUI:
:
OgreCEGUIRenderer(mWindow,
Ogre:
:
RENDER_QUEUE_OVERLAY,false,3000,mSceneMgr);
mGUISystem=newCEGUI:
:
System(mGUIRenderer);
CEGUI:
:
Logger:
:
getSingleton().setLoggingLevel(CEGUI:
:
Informative);
创建一个新的CEGUI系统,使用“TaharezLook”来设置图(sheme)与鼠标指针,使用“BlueHighway-12”来设置字体。
CEGUI:
:
SchemeManager:
:
getSingleton().loadScheme((CEGUI:
:
utf8*)"TaharezLookSkin.scheme");
mGUISystem->setDefaultMouseCursor((CEGUI:
:
utf8*)"TaharezLook",(CEGUI:
:
utf8*)"MouseArrow");
CEGUI:
:
MouseCursor:
:
getSingleton().setImage("TaharezLook","MouseMoveCursor");
mGUISystem->setDefaultFont((CEGUI:
:
utf8*)"BlueHighway-12");
mEditorGuiSheet=CEGUI:
:
WindowManager:
:
getSingleton().createWindow((CEGUI:
:
utf8*)"DefaultWindow",
(CEGUI:
:
utf8*)"Sheet");
mGUISystem->setGUISheet(mEditorGuiSheet);
}
调用自定义的帧监听器,这样我们可以在需要时访问“mGUIRender”。
voidcreateFrameListener(void)
{
mFrameListener=newGuiFrameListener(mWindow,mCamera,mGUIRenderer);
mRoot->addFrameListener(mFrameListener);
}
};
下面是主函数也是程序的主循环,在本教程并不需要你修改这段代码。
#ifOGRE_PLATFORM==OGRE_PLATFORM_WIN32
#defineWIN32_LEAN_AND_MEAN
#include"windows.h"
INTWINAPIWinMain(HINSTANCEhInst,HINSTANCE,LPSTRstrCmdLine,INT)
#else
intmain(intargc,char**argv)
#endif
{
//Createapplicationobject
TutorialApplicationapp;
try{
app.go();
}catch(Exception&e){
#ifOGRE_PLATFORM==OGRE_PLATFORM_WIN32
MessageBox(NULL,e.getFullDescription().c_str(),"Anexceptionhasoccured!
",MB_OK|MB_ICONERROR|MB_TASKMODAL);
#else
fprintf(stderr,"Anexceptionhasoccured:
%s\n",e.getFullDescription().c_str());
#endif
}
return0;
}
完成后,编译程序能得到一个空的窗口。
请关掉程序,继续我们的学习。
注意:
如果实际操作中出现问题,你可以在应用程序所在文件夹中找到“CEGUI.log”文件分析查找错误
CEGUI是如何工作的
本质上CEGUI是通过向窗口添加第二个场景,这个场景是在Ogre的基本渲染队列完成后才渲染的。
这个场景仅仅是由一系列3D矩形对象组成的。
(也就是两个多边形沿着其边压制到一起)。
渲染矩阵是为消除矩形的突兀与歪斜而根据他们的位置建立的。
使用这些矩形,添加材质和响应就构成了用户界面(GUI)。
一般情况下这是很不错的,因为一个3D的用户界面将会自动的缩放其元素来适应屏幕,并且使用硬件材质过滤。
其将会比C++标准的2D用户界面更加快速和漂亮。
“Soinonesentence:
CEGUIrendersa2Dguiusing3Dmethodsandhardwaresoyoudon'thaveto.”——zeroskill
添加退出按钮
首先,我们需要为应用程序添加下面的头文件。
本例中是“PushButton”
#include
我们要在场景底部添加退出按钮。
CEGUI:
:
PushButton*quitButton=(CEGUI:
:
PushButton*)CEGUI:
:
WindowManager:
:
getSingleton().createWindow
("TaharezLook/Button",(CEGUI:
:
utf8*)"Quit");
mEditorGuiSheet->addChildWindow(quitButton);
quitButton->setPosition(CEGUI:
:
Point(0.35f,0.45f));
quitButton->setSize(CEGUI:
:
Size(0.3f,0.1f));
quitButton->setText("Quit");
完成后执行程序,一个漂亮的按钮将会出现在屏幕中。
但请注意,程序此时仍然不做任何事情,因为我们并没有为其添加响应时间。
如果你编译时遇到了setPosition()和setSize()的调用错误:
'CEGUI:
:
Window:
:
setPosition' :
cannotconvertparameter1from'CEGUI:
:
Vector2'to'constCEGUI:
:
UVector2&'
将setPosition()和setSize()所在行分别用下面的代码替换:
quitButton->setPosition(CEGUI:
:
UVector2(cegui_reldim(0.35f),cegui_reldim(0.45f)));
quitButton->setSize(CEGUI:
:
UVector2(cegui_reldim(0.35f),cegui_reldim(0.1f)));
响应事件
将下面函数添加到TutorialApplication的public:
中
voidsetupEventHandlers(void)
{
CEGUI:
:
WindowManager&wmgr=CEGUI:
:
WindowManager:
:
getSingleton();
wmgr.getWindow((CEGUI:
:
utf8*)"Quit")->subscribeEvent(CEGUI:
:
PushButton:
:
EventClicked,CEGUI:
:
Event:
:
Subscriber
(&TutorialApplication:
:
handleQuit,this));
}
boolhandleQuit(constCEGUI:
:
EventArgs&e)
{
static_cast(mFrameListener)->requestShutdown();
returntrue;
}
重写GuiFrameListener类来响应键盘和鼠标输入
classGuiFrameListener :
publicExampleFrameListener,publicMouseMotionListener,publicMouseListener
{
private:
CEGUI:
:
Renderer*mGUIRenderer;
boolmShutdownRequested;
public:
//NBusingbufferedinput
GuiFrameListener(RenderWindow*win,Camera*cam,CEGUI:
:
Renderer*renderer)
:
ExampleFrameListener(win,cam,true,true),
mGUIRenderer(renderer),
mShutdownRequested(false)
{
mEventProcessor->addMouseMotionListener(this);
mEventProcessor->addMouseListener(this);
mEventProcessor->addKeyListener(this);
}
//Telltheframelistenertoexitattheendofthenextframe
voidrequestShutdown(void)
{
mShutdownRequested=true;
}
boolframeEnded(constFrameEvent&evt)
{
if(mShutdownRequested)
returnfalse;
else
returnExampleFrameListener:
:
frameEnded(evt);
}
voidmouseMoved(MouseEvent*e)
{
CEGUI:
:
System:
:
getSingleton().injectMouseMove(
e->getRelX()*mGUIRenderer->getWidth(),
e->getRelY()*mGUIRenderer->getHeight());
e->consume();
}
voidmouseDragged(MouseEvent*e)
{
mouseMoved(e);
}
voidmousePressed(MouseEvent*e)
{
CEGUI:
:
System:
:
getSingleton().injectMouseButtonDown(
convertOgreButtonToCegui(e->getButtonID()));
e->consume();
}
voidmouseReleased(MouseEvent*e)
{
CEGUI:
:
System:
:
getSingleton().injectMouseButtonUp(
convertOgreButtonToCegui(e->getButtonID()));
e->consume();
}
voidmouseClicked(MouseEvent*e){}
voidmouseEntered(MouseEvent*e){}
voidmouseExited(MouseEvent*e){}
voidkeyPressed(KeyEvent*e)
{
if(e->getKey()==KC_ESCAPE)
{
mShutdownRequested=true;
e->consume();
return;
}
CEGUI:
:
System:
:
getSingleton().injectKeyDown(e->getKey());
CEGUI:
:
System:
:
getSingleton().injectChar(e->getKeyChar());
e->consume();
}
voidkeyReleased(KeyEvent*e)
{
CEGUI:
:
System:
:
getSingleton().injectKeyUp(e->getKey());
e->consume();
}
voidkeyClicked(KeyEvent*e)
{
//Donothing
e->consume();
}
};
Ogre1.4.0
如果你使用的是Ogre1.4.0你将会要使用OIS。
在Ogre3d中使用OIS的更多细节,请参阅使用OIS并且再看一看基础教程5:
classGuiFrameListener :
publicExampleFrameListener,publicOIS:
:
MouseListener,publicOIS:
:
KeyListener
{
private:
CEGUI:
:
Renderer*mGUIRenderer;
boolmShutdownRequested;
public:
//NBusingbufferedinput
GuiFrameListener(RenderWindow*win,Camera*cam,CEGUI:
:
Renderer*renderer)
:
ExampleFrameListener(win,cam,true,true),
mGUIRenderer(renderer),
mShutdownRequested(false)
{
mMouse->setEventCallback(this);
mKeyboard->setEventCallback(this);
}
//Telltheframelistenertoexitattheendofthenextframe
voidrequestShutdown(void)
{
mShutdownRequested=true;
}
boolframeEnded(constFrameEvent&evt)
{
if(mShutdownRequested)
returnfalse;
else
returnExampleFrameListener:
:
frameEnded(evt);
}
boolmouseMoved(constOIS:
:
MouseEvent&e)
{
usingnamespaceOIS;
CEGUI:
:
System:
:
getSingleton().injectMouseMove(e.state.X.rel,e.state.Y.rel);
returntrue;
}
boolmousePressed(constOIS:
:
MouseEvent&e,OIS:
:
MouseButtonIDid)
{
CEGUI:
:
System:
:
getSingleton().injectMouseButtonDown(convertOgreButtonToCegui(id));
returntrue;
}
boolmouseReleased(constOIS:
:
MouseEvent&e,OIS:
:
MouseButtonIDid)
{
CEGUI:
:
System:
:
getSingleton().injectMouseButtonUp(convertOgreButtonToCegui(id));
returntrue;
}
boolkeyPressed(constOIS:
:
KeyEvent&e)
{
if(e.key==OIS:
:
KC_ESCAPE)
{
mShutdownRequested=true;
returntrue;
}
CEGUI:
:
System:
:
getSingleton().injectKeyDown(e.key);
CEGUI:
:
System:
:
getSingleton().injectChar(e.text);
returntrue;
}
boolkeyReleased(constOIS:
:
KeyEvent&e)
{
CEGUI:
:
System:
:
getSingleton().injectKeyUp(e.key);
returntrue;
}
};
在include语句后GuiFrameListener声明前添加下面代码
CEGUI:
:
MouseButtonconv