Posts Tagged ‘ CEGUI

CEGUI的Event動畫

在以前介紹過CEGUI的Animation部分,在其中的Subscription的Element並未作出解釋,今天我們來解釋一下這個.

先來回顧一個CEGUI帶的Sample的Animation文件:

<?xml version="1.0" ?>
<Animations>

    <AnimationDefinition name="Example1A" duration="0.3" replayMode="once">
        <Affector property="Alpha" interpolator="float">
            <KeyFrame position="0" value="1" />
            <KeyFrame position="0.3" value="0.66" progression="quadratic decelerating" />
        </Affector>
        <Subscription event="MouseLeavesArea" action="Start" />
    </AnimationDefinition>

    <AnimationDefinition name="Example1B" duration="0.3" replayMode="once">
        <Affector property="Alpha" interpolator="float">
            <KeyFrame position="0" value="0.66" />
            <KeyFrame position="0.3" value="1" progression="quadratic accelerating" />
        </Affector>
        <Subscription event="MouseEntersArea" action="Start" />
    </AnimationDefinition>

</Animations>

Subscription是Event動畫的定義,類似於:當發生MouseEntersArea事件的時候,就會觸發這個動畫的Start行為.

Read more

CEGUI的Event部分

CEGUI的Event部分據說做的比較複雜,但是看到MyGUI的託管機制實現的事件系統覺得貌似MyGUI的應該更複雜一點.

CEGUI的事件還是比較直觀的,下面寫篇小網誌來簡單介紹一下CEGUI的事件系統.

在挂件Window的這個Base Class是繼承了PropertySet和EventSet類的,PropertySet類以前已經介紹過,現在來介紹一下稍微比PropertySet複雜的EventSet.

EventSet負責維護著一個Event的Map,這個Map大概這樣:

std::map<String,Event*> d_events;

其中String表示事件名稱,而Event*則對應事件體.

我們首先來看EventSet的接口,她是如何給一個事件添加一個Event綁定函式的.

EventSet下面有如下接口:

virtual Event::Connection subscribeEvent(const String& name, Event::Subscriber subscriber);
virtual Event::Connection subscribeEvent(const String& name, Event::Group group, Event::Subscriber subscriber);
virtual void fireEvent(const String& name, EventArgs& args, const String& eventNamespace = "");

subscribeEvent表示綁定一個函式指針到某個事件上,而fireEvent則表示執行這個事件綁定的所有函式.

客戶在使用的時候,先調用subscribeEvent綁定了自己的處理事件的函式,然後當這個事件發生的時候便可以自動執行這些函式。
Read more

CEGUI的動畫解析

CEGUI能夠支援的動畫有很多種,應該說凡是WindowsProperties namespace裡面有的Window的Property,她都能夠支援。這是CEGUI的動畫部分設計的非常靈活導致的.

我們首先來看AnimationManager,這是所有Animation的總管.

她的關鍵的成員變量有如下幾種類型:

std::map<String, Interpolator*> d_interpolators;
std::map<String, Animation*> d_animations;
std::multimap<Animation*, AnimationInstance*> d_animationInstances;

Interpolator類是一個計算器類,用來計算兩個關鍵幀之間的屬性增量值.

Animation是動畫體類,單個動畫體的內容就在這個類裡.

AnimationInstance則用來控制這個Animation的播放和鏈接到Window操作.

首先我們來看Interpolator類,這是一個純虛類,聲明如下:

Read more

CEGUI屬性部分

CEGUI的屬性部分顯的比較複雜,下面來看看.

CEGUI的Window類是一切控件的Base Class,這個class繼承與PropertySet類和EventSet兩個class。EventSet是事件管理,這次來說說PropertySet屬性部分.

首先要說明的是,在CEGUI中,每一種屬性都是一個class,待會詳細描述.

一個屬性的基類為Property,這個類定義如下:

class CEGUIEXPORT Property
{
public:
	Property(const String& name, const String& help, const String& defaultValue = "", bool writesXML = true) :
	  d_name(name),
	  d_help(help),
	  d_default(defaultValue),
	  d_writeXML(writesXML)
	{
	}
	virtual ~Property(void) {}
	const String& getHelp(void) const		{return d_help;}
	const String& getName(void) const		{return d_name;}
	virtual String	get(const PropertyReceiver* receiver) const = 0;
	virtual void	set(PropertyReceiver* receiver, const String& value) = 0;
	virtual bool	isDefault(const PropertyReceiver* receiver) const;
	virtual String	getDefault(const PropertyReceiver* receiver) const;
        virtual void writeXMLToStream(const PropertyReceiver* receiver, XMLSerializer& xml_stream) const;

protected:
	String	d_name;		//!< String that stores the Property name.
	String	d_help;		//!< String that stores the Property help text.
	String	d_default;	//!< String that stores the Property default value string.
	bool    d_writeXML; //!< Specifies whether writeXMLToStream should do anything for this property.
};

類裡面有四個成員變量,分別為名稱,幫助信息,默認值和是否寫入到XML檔標記。那麼我們的真正的屬性值存儲在哪裡呢?

Read more

CEGUI,OIS和DirectX的結合

這裡所說的OIS是指Object-Oriented Input System,一個可以跨平台的開源輸入系統。

網路上面搜索OIS的使用教程,基本都是和Ogre引擎結合的,而Aquilae 2是使DirectX 10的,所以在這裡直接寫個OIS以及CEGUI在DirectX環境下面的使用.

首先來看OIS:

先來這裡下載:http://sourceforge.net/projects/wgois/ 然後編譯成一個lib.

在自己的project裡面include”OIS.h”即可,然後在鏈接到那個編譯好的lib.

這裡木有包含遊戲桿的設備初始化,只有鍵盤和鼠標:

OIS::InputManager        *m_pInputManager;      //OIS輸入管理員
OIS::Mouse                *m_pMouse;              //OIS輸入鼠標器
OIS::Keyboard            *m_pKeyboard;          //OIS輸入鍵盤

InputManager對象是必須的,她負責整個輸入系統下面的運作。

接著再進行OIS的創建和初始化:

m_pInputManager = OIS::InputManager::createInputSystem((size_t)m_Hwnd);
m_pKeyboard = static_cast(m_pInputManager->createInputObject( OIS::OISKeyboard, true ));
m_pMouse = static_cast(m_pInputManager->createInputObject( OIS::OISMouse, true));

其中,m_Hwnd是窗口的句柄。createInputObject( OIS::OISMouse, true)這裡面參數true的意思是使用緩衝模式,如果你想使用監聽器來監聽輸入設備,那麼這裡的true參數是必須的。

下面我們開始說輸入設備的監聽器:

這裡的監聽器同時負責鼠標和鍵盤的監聽,所以得繼承來自兩個類:

class InputDeviceListener
	:public OIS::MouseListener,public OIS::KeyListener
{
public:
	//----------------------------------------------------------------------------------
	//構造函式
	//----------------------------------------------------------------------------------
	InputDeviceListener();
	//----------------------------------------------------------------------------------
	//析構函式
	//----------------------------------------------------------------------------------
	~InputDeviceListener();
public:
	//----------------------------------------------------------------------------------
	//鼠標按下
	//----------------------------------------------------------------------------------
	bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id);
	//----------------------------------------------------------------------------------
	//鼠標釋放
	//----------------------------------------------------------------------------------
	bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id);
	//----------------------------------------------------------------------------------
	//鼠標移動
	//----------------------------------------------------------------------------------
	bool mouseMoved(const OIS::MouseEvent &evt);
	//----------------------------------------------------------------------------------
	//鍵盤按下
	//----------------------------------------------------------------------------------
	bool keyReleased(const OIS::KeyEvent &evt );
	//----------------------------------------------------------------------------------
	//鍵盤按下
	//----------------------------------------------------------------------------------
	bool keyPressed(const OIS::KeyEvent &evt );
};

Read more

Visual Studio 2010編譯OGRE和CEGUI小記

Visual Studio 2010已經發布很多時日了,OGRE和CMAKE也跟進很快,通過CMAKE很容易能夠立即生成OGRE的Visual Studio 2010的項目文件,編譯即可.

但是不巧的是,CEGUI使用的是Premake,而Premake到目前為止版本4.21還是沒能支持Visual Studio 2010,只能最多生成Visual Studio 2008的項目文件.

好吧,那就就先生成Visual Studio 2008的文件吧,執行CEGUI原始碼premake目錄下面的build_vs2008.bat,生成了Visual Studio 2008的項目,接著用Visual Studio 2010打開,然後轉換這個項目成Visual Studio 2010的.

然後開始編譯,有大牛報告說因為CEGUI的某處不太嚴格,導致Visual Studio 2010編譯失敗,會報這樣的錯誤:

1> CEGUIMultiColumnList.cpp
1>d:program filesmicrosoft visual studio 10.0vcincludexmemory(205): error C2440: ‘initializing’ : cannot convert from ‘int’ to ‘CEGUI::ListboxItem *’
1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast

打開CEGUIMultiColumnList.cpp,改成:

d_grid[i].d_items.insert(d_grid[i].d_items.begin() + position, 0 );

改成

Read more

return top