Ogre笔记九:基础教程六—CEGUI和Ogre

      前几章为了简单方便,把教程里的代码一股脑儿全堆在一个.cpp文件中,这只是初学者的做法,到以后我们做项目,就要学会分清结构。前面几个例子的代码太少不方便分开,这一课的代码分开就比较清晰了,请注意:这很重要。

      首先,像以前一样先搞懂我们要做什么,这一节我们没有3D场景,只需添加一个退出按钮,再给按钮加上事件,看上去简单

然后,看一下结构:


Main.cpp(项目入口,教程中说不改这里的代码,但是这个东东可以很简单几句话就行了,算了我们还是听教程的好)

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "Headfile.h"
#include "windows.h"
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
	// Create application object
	TutorialApplication app;
	try {
		app.go();
	} catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK |
			MB_ICONERROR | MB_TASKMODAL);
#else
		fprintf(stderr, "An exception has occured: %s\n",e.getFullDescription().c_str());
#endif
	}
	return 0;
}

Headfile.h(此文件中是必要的包含文件)

#ifndef HEADFILE_H
#define HEADFILE_H
//........
//........
#endif


先解释一下这个东西好像是防止重包含的,我也不怎么清楚,反正上次报错,这样做就好了,所以我把所有的.h(头文件)全改成这样了

#ifndef HEADFILE_H
#define HEADFILE_H

//CEGUI包含文件
#include <CEGUI/CEGUIImageset.h>
#include <CEGUI/CEGUISystem.h>
#include <CEGUI/CEGUILogger.h>
#include <CEGUI/CEGUISchemeManager.h>
#include <CEGUI/CEGUIWindowManager.h>
#include <CEGUI/CEGUIWindow.h>
#include <CEGUI/elements/CEGUIPushButton.h>
#include "OgreCEGUIRenderer.h"
#include "OgreCEGUIResourceProvider.h"

//regular mem handler
#include "ExampleApplication.h"

// OIS输入输出系统头文件
#include <OIS/OIS.h>
using namespace OIS;

//本项目文件
#include "FrameListener.h"
#include "ExampleApp.h"

#endif

ExampleApp.h

#ifndef EXAMPLEAPP_H
#define EXAMPLEAPP_H
#include "Headfile.h"

class TutorialApplication : public ExampleApplication
{
private:
	CEGUI::OgreCEGUIRenderer* mGUIRenderer;
	CEGUI::System* mGUISystem;
	CEGUI::Window* mEditorGuiSheet;
public:
	TutorialApplication();

	~TutorialApplication();

	void setupEventHandlers(void);

	bool handleQuit(const CEGUI::EventArgs& e);

protected:
	void createScene(void);

	void createFrameListener(void);
};

#endif

ExampleApp.cpp

#include "ExampleApp.h"

TutorialApplication::TutorialApplication()
: mGUIRenderer(0),
mGUISystem(0),
mEditorGuiSheet(0)
{
}
TutorialApplication::~TutorialApplication()
{
	if(mEditorGuiSheet)
	{
		CEGUI::WindowManager::getSingleton().destroyWindow(mEditorGuiSheet);
	}
	if(mGUISystem)
	{
		delete mGUISystem;
		mGUISystem = 0;
	}
	if(mGUIRenderer)
	{
		delete mGUIRenderer;
		mGUIRenderer = 0;
	}
}

void TutorialApplication::createScene(void)
{
	// Set ambient light
	mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
	// 初始化GUI
	mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr);
	mGUISystem = new CEGUI::System(mGUIRenderer);
	CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);
	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);

	//手动新建一个退出按钮,设置它的大小、位置
	//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->setPosition(CEGUI::UVector2(cegui_reldim(0.35f), cegui_reldim( 0.45f)) );
	//quitButton->setSize(CEGUI::UVector2(cegui_reldim(0.35f), cegui_reldim( 0.1f)) );
	//quitButton->setText("Quit");

//*************************************************************************************************************
//                       用.xml创建界面         
	mEditorGuiSheet = CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)"TutoralGui.xml");
	mGUISystem->setGUISheet(mEditorGuiSheet);
	CEGUI::PushButton* quitButton=(CEGUI::PushButton*)CEGUI::
	WindowManager::getSingleton().getWindow((CEGUI::utf8*)"Quit");

	setupEventHandlers();
}

void TutorialApplication::createFrameListener(void)
{
	mFrameListener = new GuiFrameListener(mWindow, mCamera, mGUIRenderer);
	mRoot->addFrameListener(mFrameListener);
}

void TutorialApplication::setupEventHandlers(void)
{
	CEGUI::WindowManager& wmgr = CEGUI::WindowManager::getSingleton();
	wmgr.getWindow((CEGUI::utf8*)"Quit")->subscribeEvent(CEGUI::PushButton::EventClicked,
		CEGUI::Event::Subscriber
		(&TutorialApplication::handleQuit, this));
}

bool TutorialApplication::handleQuit(const CEGUI::EventArgs& e)
{
	static_cast<GuiFrameListener*>(mFrameListener)->requestShutdown();
	return true;
}

其中有地方用到了“TutoralGui.xml”文件

复制下面xml代码到记事本,并将其以“TutoralGui.xml”命名另存在“\media\gui”文件夹下

<?xml version="1.0" ?>
<GUILayout>
<Window Type="DefaultWindow" Name="Tutorial Gui">
<Window Type="TaharezLook/Button" Name="Quit">
<Property Name="UnifiedPosition" Value="{{0.35,0},{0.45,0}}" />
<Property Name="UnifiedSize" Value="{{0.3,0},{0.1,0}}" />
<Property Name="Text" Value="Quit" />
</Window>
</Window>
</GUILayout>
这样做的效果跟手动创建GUI是一样的,其实.xml文件可以很方便得产生,下一节介绍怎样用CELayoutEditor制作界面

FrameListener.h

#ifndef GUILISTENER_H
#define GUILISTENER_H

#include "Headfile.h"

class GuiFrameListener : public ExampleFrameListener, public OIS::MouseListener, public OIS::KeyListener
{
private:
	CEGUI::Renderer* mGUIRenderer;
	bool mShutdownRequested;
public:
	GuiFrameListener(RenderWindow* win, Camera* cam, CEGUI::Renderer* renderer);

	void requestShutdown(void);

	bool frameEnded(const FrameEvent& evt);

	bool mouseMoved( const OIS::MouseEvent &e );

	bool mousePressed (const OIS::MouseEvent &e, OIS::MouseButtonID id);

	bool mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id );

	bool keyPressed( const OIS::KeyEvent &e );

	bool keyReleased( const OIS::KeyEvent &e );
};

#endif

FrameListener.cpp

#include "Headfile.h"
#include "FrameListener.h"

CEGUI::MouseButton convertOgreButtonToCegui(int buttonID)
{
	using namespace OIS;
	switch (buttonID)
	{
	case OIS::MB_Left:
		return CEGUI::LeftButton;
	case OIS::MB_Right:
		return CEGUI::RightButton;
	case OIS::MB_Middle:
		return CEGUI::MiddleButton;
	default:
		return CEGUI::LeftButton;
	}
}

// NB using buffered input
GuiFrameListener::GuiFrameListener(RenderWindow* win, Camera* cam, CEGUI::Renderer* renderer)
: ExampleFrameListener(win, cam, true, true),
mGUIRenderer(renderer),
mShutdownRequested(false)
{
	mMouse->setEventCallback( this );
	mKeyboard->setEventCallback( this );
}

// Tell the frame listener to exit at the end of the next frame
void GuiFrameListener::requestShutdown(void)
{
	mShutdownRequested = true;
}

bool GuiFrameListener::frameEnded(const FrameEvent& evt)
{
	if (mShutdownRequested)
		return false;
	else
		return ExampleFrameListener::frameEnded(evt);
}

bool GuiFrameListener::mouseMoved( const OIS::MouseEvent &e )
{
	using namespace OIS;
	CEGUI::System::getSingleton().injectMouseMove(e.state.X.rel,e.state.Y.rel);
	return true;
}

bool GuiFrameListener::mousePressed (const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
	CEGUI::System::getSingleton().injectMouseButtonDown(convertOgreButtonToCegui(id));
	return true;
}

bool GuiFrameListener::mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id )
{
	CEGUI::System::getSingleton().injectMouseButtonUp(convertOgreButtonToCegui(id));
	return true;
}

bool GuiFrameListener::keyPressed( const OIS::KeyEvent &e )
{
	if(e.key == OIS::KC_ESCAPE)
	{
		mShutdownRequested = true;
		return true;
	}
	CEGUI::System::getSingleton().injectKeyDown(e.key);
	CEGUI::System::getSingleton().injectChar(e.text);
	return true;
}

bool GuiFrameListener::keyReleased( const OIS::KeyEvent &e )
{
	CEGUI::System::getSingleton().injectKeyUp(e.key);
	return true;
}

最后的效果:


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值