更多精彩內容,請見:http://www.16boke.com
cegui1cegui渲染入門
至少需要3步,才可以使cegui運行起來
1創建CEGUI::Renderer對象
2創建CEGUI::System對象
3調用渲染函數
1創建CEGUI:Renderer對象
支持的渲染組件(Direct3d9OpenGlOgre3detc..)
記得包含所使用的渲染組件的頭文件。
Direct3D8.1
CEGUI::Directx81Renderer*myRenderer=newCEGUI::Directx81Renderer(myD3D89Device);
Direct3D9
CEGUI::Directx9Renderer*myRenderer=newCEGUI::Directx9Renderer(myD3D9Device,0);
OpenGl
CEGUI::OpenGLRenderer*myRenderer=newCEGUI::OpenGLRenderer(0);
Ogre3d
CEGUI::OgreCEGUIRenderer*=newCEGUI::OgreCEGUIRenderer(myRenderWindow)
2創建CEGUI::System對象來對系統進行初始化
僅僅new一個CEGUI::System對象。并把剛才創建的CEGUI::Renderer對象的指針傳送給他,這時整個系統將會自動初始化。
newCEGUI::System(myRenderer)
3調用渲染函式
這一步與所使用的引擎不同。你要做的就是每幀渲染之后調用CEGUI::System::renderGUI而已。Ogre3d會自動完成這步。對于其他引擎也很簡單。
Direct3D81/9
myD3DDevice->BeginScene();
myD3DDevice->Clear(0,0,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
draw3DScene();
CEGUI::System::getSingleton().renderGUI();
myD3DDevice->EndScene();
myD3DDevice->Present(0,0,0,0);
cegui2資源管理入門
設置資源管理組(resourceprovidergroups),我們將用它們裝載一些文件供CEGUI在渲染的時候使用。
ResourceProvide是什么?
CEGUI使用了一個工具對象,我們叫它“ResourceProvide”。這個對象提供了一組接口負責CEGUI與其他的文件裝載系統通訊。
例如:Ogre和Irrlicht都有他們自己的資源管理/文件裝載子系統,通過實現特定的ResourceProvide對象,CEGUI
的渲染模塊就和那些子系統無縫的組合起來。那樣CEGUI的數據文件就可以通過那些子系統裝載了。但是,更底層的庫(Direct3DOpenGL)沒有那樣的資源管理系統。所以CEGUI為他們提供了默認的資源管理系統(defaultresourceprovider)。
defaultresourceprovider相關說明
CEGUI::DefaultResourceProvider——–CEGUI的默認的資源管理系統,是為那些還沒有資源管理的庫提供基礎幫助的系統。他不僅提供了CEGUI裝載文件數據時所需要的函數,而且對資源組(resourcegroups)也提供了初步的支持。這里的“資源組”其實只是一個標簽,它代表系統的某個文件夾路徑。這使得我們可以將文件夾中的文件按邏輯類型分組,然后可以通過一個人簡單的標簽而不是硬編碼的路徑去指定它,也就是說:當數據文件的路徑有改動的時候,只需要更細資源組的路徑而不必更改代碼和xml文件中的路徑信息。
指定資源組和路徑DefaultResourceProvider允許你定義任意數目的資源組,并為每個資源組指定一個路徑。也就是說,你可以創建一個資源組,比如“imagesets”,并為它指定一個路徑,假設是”./game/datafile/gui/imagesets/”.然后,你通過ImagesetManager裝載Imageset的時候,就可以指定”imagesets”為他將要使用的資源組,這樣系統就會在預定義的路徑中尋找資源。目前,每個資源組只可以賦予一個路徑。
舉例子說明
以前,在沒有使用資源組的時候,你也許
Imageset*set=ImagesetManager::getSingleton().createImageset(“./game/datafile/gui/imagesets/WindowsLook.imageset”);
使用了資源組以后,在初始化階段,你可以使用默認的資源管理器像這樣創建資源組
DefaultResourceProvider*rp=CEGUI::System::getSingleton().getResourecProvider();
rp->setResourcrGroupDirectory(“imagesets”,”(“./game/datafile/gui/imagesets/WindowsLook.imageset”);
Imageset*set=ImagesetManager::getSingleton().createImageset(“WindowsLook.imageset”,”imagesets”)
注意:你不需要提供任何的路徑信息,因為在你指定的資源組中已經包含了相關的路徑信息。
默認資源組
系統定義的任何代表可以可裝載資源的資源類,都有獲取和設置默認資源組的靜態函數。
當需要載入數據文件的時候,他就用那個默認資源組。比如:對于Imageset類,默認的資源組應該指向一個存儲imagesetxml文件和材質文件的文件夾。
對于每個資源類,他們獲取設置資源組的靜態函數的名字都是一樣的(xerces是個例外)
constString&getDefaultResourceGroup();
voidsetDefaultResourceGroup(cosntString&groupname);
如果是資源類的一個列表,后面是他們各自管理的資源類型
CEGUI::Imageset——-Imagesetxmlandtextureimagefiles
CEGUI::Font———-Fontxmlandttffontfiles.
CEGUI::Scheme——-Schemexmlfiles
CEGUI::WindowManager———windowlayoutxmlfiles
CEGUI::WidgetLookManager———-LookNFeelxmlfiles
CEGUI::ScriptModule———Scriptfilesinwhicheverscriptedlangauge
上面提到過,xerces是個例外,它是“基于Xerces-C的XML解釋器(Xerces-CbasedXMLparser)”。對此,有一個特殊的資源組設置文件,它指明schema文件在哪里(它們是用來檢查xml的.xsd文件)。對于這個特殊情況,它的靜態成員如下:
constString&XercesParser::getSchemaDefaultResourceGroup();
voidXercesParser::setSchemaDefaultResourceGroup(constString&groupname);
需要注意的最后一點是:資源管理類也有一個默認的資源組。當一個資源類沒有顯示的指定資源組的時候,系統就會使用它。當你把所有的數據文件都放到一個文件夾的時候,這點就很方便了。
一個完整的例子:配置DefaultResourceProvider
1//為DefaultResourceProvider設置所需的路徑
2CEGUI::DefaultResourceProvider*rp=static_cast
3(CEGUI::System::getSingleton().getResourceProvider());
4
5rp->setResourceGroupDirectory(“schemes”,“../datafiles/schemes/”);
6rp->setResourceGroupDirectory(“imagesets”,
7“../datafiles/imagesets/”);
8rp->setResourceGroupDirectory(“fonts”,“../datafiles/fonts/”);
9rp->setResourceGroupDirectory(“layouts”,“../datafiles/layouts/”);
10rp->setResourceGroupDirectory(“looknfeels”,
11“../datafiles/looknfeel/”);
12rp->setResourceGroupDirectory(“lua_scripts”,
13“../datafiles/lua_scripts/”);
14
15//這步僅當你使用Xerces作為XML解析器的時候才需要
16rp->setResourceGroupDirectory(“schemas”,“../../XMLRefSchema/”);
完成這步以后,我們就把資源組和它們的路徑都設置好了。最后,為了讓系統使用新設置的路徑,我們來設置默認資源組:
17//設置默認資源組
18CEGUI::Imageset::setDefaultResourceGroup(“imagesets”);
19CEGUI::Font::setDefaultResourceGroup(“fonts”);
20CEGUI::Scheme::setDefaultResourceGroup(“schemes”);
21CEGUI::WidgetLookManager::setDefaultResourceGroup(“looknfeels”);
22CEGUI::WindowManager::setDefaultResourceGroup(“layouts”);
23CEGUI::ScriptModule::setDefaultResourceGroup(“lua_scripts”);
24
25//僅當你用xerces做XML解析器,并為它定義了一個資源組的時候使用
26CEGUI::XercesParser::setSchemaDefaultResourceGroup(“schemas”);
cegui3數據文件的裝載和初始化
只有裝載了數據文件,CEGUI才會產生想要的輸出..
數據文件概述
CEGUI使用多種類型的數據文件.
xmlxsd?都是xml
CEGUI使用的大多說文件都是xml格式的,除了那些特殊的圖片以及可以裝載的模塊文件(DLL),說到這里大家可能會想到那個特殊的.xsd文件.盡管現在CEGUI的默認xml解析庫是ExpatXML解析庫,可是CEGUI以前一直使用的是Xerces-C++庫作為她的xml解析庫.CrazyEddies本人也更喜歡這個庫,這個庫的優勢是它提供模式驗證(schemavalidation).通過模式驗證,我們可以在解析期間檢測輸入文件是否包含需要的數據以及數據是否正確的設置.系統需要一個額外的文件才可以做到這個.他們就是以.xsd作為后綴的模式文件CEGUI的模式文件存放在cgui_mk2/XMLRefSchema/目錄下.目前,對于.xsd文件,你只需知道,當把Xerce-C++用作xml解析器的時候,必須讓ResourceProvider系統可以找到他們.要做到這一點很簡單那,只需要設置一個資源組,把此資源組關聯到一個包含.xsd文件的文件夾,并把這個資源組設置為CEGUI::XeracesParser裝載.xsd文件是所使用的資源組.
數據文件
為了清晰的說明數據文件代表什么類型的資源.數據文件并不是都是以.xml作為后綴,而是以更有意義的后綴名.比如Imageset的后綴名是.imageset,Font的后綴.font等等
Imageset
為了效率,通常我們把材質文件等圖片組合成到一個大的材質圖片,在使用的時候在上面截取
各個小的材質.而這個Imageset就是保存各個小材質在整個源圖片的區域信息的.源圖片也在
里面指定了,每個區域都有一個獨一無二的名字,當提到他名字的時候,系統就把他當作圖片處理.所以,可以說Imageset定義了一系列圖片,通過修改Imageset中的源圖片名,各個區域的位置和大小,就可以輕松的改變所繪制的GUI的外觀了.
Font
顯然是定義了CEGUI使用的字體.所能定義的字體類型有2種
FreeTypeFont
這是一種基于true-type(.ttf)的字體文件.從CEGUI0.5.0開始,在.font文件中用Type=”FreeType”指定這種字體類型,在更早的版本中,用”Dynamic”指定.
PixmapFont
位圖字體.這種字體基于一個定義了文字圖片的Imageset.從CEGUI0.5.0開始,在.font文件中使用Type=”Pixmap”指定該字體,在更早的版本中,使用”Static”指定.
Scheme
該文件是把其他數據文件聯系到一起的主要手段,同時他也是裝載和定義各種控件最方便的方法.
一個Scheme文件可以把下面的一個或者多個文件.
(當Scheme文件被載入的時候,他所包含的文件也被載入并且初始化)
Imageset
Font
WindowSet
WindowRendererSet
WindowAlias
FalagardMapping
WindowSet主要用來指明一個可載入的模塊.dll.so等.并列出他所使用的控件中你想注冊的控件的名字.如果沒有列出任何空間名,那么模塊中的所有控件都將被注冊.
WindowAlias
提供通過別名可以指定一個窗口/空間類型的方法.用此方法,也可以使用另一個控件類型來”替代”一個已經注冊的空間類型,這樣就達到了隱藏已注冊控件的效果.
WindowRendererSet
指明一個可載入模塊(.dll等)的名字,并列出它所使用的窗口渲染器(windowrenderer)中你想注冊的窗口渲染器的名字。如果沒有列出任何窗口渲染器名,那么模塊中所有的窗口渲染器都將被注冊?!按翱阡秩酒鳌笔且粋€可以控制基本窗口類型渲染的東西。所有的窗口渲染器都是利用’Falagard’蒙皮系統進行渲染的(盡管這不是非常必須的)。
FalagardMapping
用來創建一個可用的WindowType類型,包含3個部分.
TargetType–指定基類(具有相關的功能);Renderer—-指定窗口渲染器(可以控制渲染指定的TargetType)
LookNFeel–指定要使用的皮膚(一般這個它們是通過XML格式的looknfeel文件指定)
Layout
文件用xml格式描述了一個窗口的布局.每個鑲嵌的”Window”元素定義一個想要創建的窗口或者控件,”Property”元素為每個定義的窗口設置相關屬性.
Config
CEGUI文件支持使用配置文i件.這個文件允許你定義一些默認參數,比如默認載入的Scheme,默認載入的Layout文件.初始化和終止腳本,以及其他沒有提到的東西.
載入基本的文件
為了成功的顯示CEGUI,你需要載入一些文件,至少是下面這些
ImagesetFontScheme
Scehme文件可以自動的載入其他的2個文件,基于教程的目的,我們將載入一個Scheme文件和一個font文件——Scheme文件會自動幫我們載入一個Imageset文件.
code:
//loadScheme,他自動loadTaharezLookimageset
CEGUI::SchemeManger::GetSingleton().loadScheme(“TaharezLook.scheme”);
載入font文件.第一個被載入的字體文件將自動成為默認字體.
if(!CEGUI::FontManger::GetSingleton().isFontPresent(“Commonwealth-10”))
CEGUI::FontManger::GetSingleton().createFont(“Commonwealth-10”);
上面的代碼假設資源組以及默認資源組都按照資源管理入門中描述的方法設置好了.
簡單的默認設置
最后需要設置一些默認值,這么做是為了確保系統總是用可用的字體和鼠標指針,以防止某個窗口或者控件沒有特別設置他自己的字體和鼠標指針.
實際上我們不需要指定一個默認字體,因為FontManager會自動的設置第一個被載入的字體作為默認字體,如果他不是你想要的默認字體.你可設置為其他的.設置的代碼如下:
System::getSingleton().setDefaultFont(“Commonwealth-10”);
另一個你需要設置默認值的是鼠標指針。這么做是為了確保當鼠標位于那些沒有設置指針的控件上時不至于消失。設置默認鼠標指針的代碼如下(本示例使用由上面的scheme載入的TaharezLookimageset):
1System::getSingleton().setDefaultMouseCursor(
2“TaharezLook”,“MouseArrow”);
如果你打算用工具提示,則需要指明你想用的基于ToolTip的控件類型名。盡管通常情況下是不需要這么做的,這也超出了這個基礎教程的范圍,其實可以在每個窗口基礎上設置它。設置工具提示窗口類型代碼如下:
3System::getSingleton().setDefaultToolTip(“TaharezLook/Tooltip”);
cegui4創建CEGUI窗口入門
講述如何創建一個簡單的CEGUI窗口.
所有的控件都是窗口
所有的控件類都是從Window這個基類派生出來的,所以,在此教程中,每當我提到一個窗口的時候,它可以是一個按鈕也可以是一個滾動條控件。
很多的設置都會被繼承下去
CEGUI中,窗口的很多的設置和屬性都會按窗口父子等級向下傳遞。比如:如果你將一個窗口的alpha透明度設置為0.5,那么,默認情況下,所有附屬于那個窗口的子窗口/組件都將受到影響。同時要注意:子窗口的實際設置并沒有改變—-最終的屬性值通常是由最頂層到當前窗口所有屬性值組合而成的。好多東西都有這個規律,比如窗口的銷毀:默認情況下,一個窗口在銷毀的時候將銷毀它的所有子窗口。這一機制最大的優點是:通過改變根窗口的alpha透明度、顯示/隱藏、激活/禁用狀態等可以很輕易的控制整個GUI;通過簡單的銷毀根窗口就可以輕松的清空整個GUI。當個別窗口需要更精確的控制或有更好的管理技術用的時候,可以更改這一默認繼承機制。
創建窗口
有兩種方法來創建窗口:通過C++硬編碼實現和通過XML布局文件實現。下面將討論這兩種方法。
CEGUI的所有窗口都是被WindowManager這一對象創建的。你可以通過getSingleton函數獲得這個對象,代碼如下:
1usingnamespaceCEGUI;
2WindowManager&wmgr=WindowManager::getSingleton();
一般情況,你將用DefaultWindow(或者它的老名字:DefaultGUISheet)作為GUI的“root”窗口。這點并不是必須的,但它是使用CEGUI很好的習慣,而且可以幫助簡化布局。下一步,我們將創建一個DefaultWindow作為GUI的根窗口(這里sheet是root的意思)。
3Window*myRoot=wmgr.createWindow(“DefaultWindow”,“root”);
4System::getSingleton().setGUISheet(myRoot);
indowManager::createWindow函數有兩個string類型的參數。第一個參數,本例中為“DefaultWindow”,告訴系統你要創建的窗口類型或類。通常,你可以使用的窗口類型是那些當你載入scheme文件的時候注冊的窗口類。而有些像DefaultWindow這樣的是全局類型,它們總是可用的。第二個參數,本例中為“root”,是一個將要賦予這個窗口的獨一無二的名字。以后可以通過這個名字獲取指向這個窗口的指針。注意:并不是一定要給你的根窗口命名為“root”,但這是通常的命名約定。
System::setGUISheet函數用來指定一個窗口作為GUI的根窗口。這將替換掉當前的根窗口,但是要注意:之前的一系列窗口/控件并沒有被銷毀,只是從當前的顯示鏈中摘除—-通過使用setGUISheet函數,你可以輕松的在多個GUI中切換。
現在,你已經創建了第一個窗口并把它附著在GUI系統上,當系統畫GUI的時候,它將把這個窗口作為GUI的根。但是,如果你編譯運行這些代碼,你依然不會看到任何東西。怎么了?你的程序沒有任何問題,問題在:我們剛才創建的DefaultWindow是隱藏的!這就是為什么DefaultWindow那么適合做根窗口的原因:它僅僅被用作供其他的窗口和控件依附的空畫布。那么,我們再加把勁吧。?!,F在,我們將要創建一個框架窗口:這個窗口和你桌面上的窗口很類似,它有一個標題欄,也可以移動和改變大小。代碼如下:
5FrameWindow*fWnd=(FrameWindow*)wmgr.createWindow(
6“TaharezLook/FrameWindow”,“testWindow”);
此代碼創建了一個“TaharezLook/FrameWindow”窗口。整個系統都使用這種命名約定:窗口類型以組件組名做為前綴(假如你載入了WindowsLookscheme,你就可以創建一個“WindowsLook/FrameWindow”對象)。我們為這個新窗口命名為“testWindow”。需要注意的是:那個類型轉換的使用,由于createWindow函數總是返回Window基類指針,盡管對于此例以及其他情況,返回這個Window指針就足夠了,但是有時你需要訪問子類的方法,所以使用CEGUI的時候示例中的類型轉換是很常見的。
為了讓系統能夠用我們的新窗口做一些有用的事情,我們還需要做一些事情。
首先,我們必須把這個新窗口附著到我們上面指定的根窗口上,代碼如下:
7myRoot->addChildWindow(fWnd);
現在,我們可以設置它的位置和大小。CEGUI使用一個“統一的(unified)”坐標系,使得可以同時使用相對部分和絕對部分—-這就是為什么你看到的每個坐標都由兩個部分組成。
8//定位在其父窗口左上角開始的1/4位置
9fWnd->setPosition(UVector2(UDim(0.25f,0),UDim(0.25f,0)));
10
11//設置其大小為其父窗口的一半
12fWnd->setSize(UVector2(UDim(0.5f,0),UDim(0.5f,0)));
最后,我們為這個框架窗口的標題欄設置一個標題:
13fWnd->setText(“HelloWorld!”);
XML布局
上面的方法看起來很不錯,但是,它有一個很大的弊端:每次你想要調整GUI布局的時候,你就得去修改代碼,然后重新編譯。這樣還不累死了?你真正想要做的是能夠把布局保存在文件中,然后在代碼中調用那個布局文件。
系統支持XML格式的布局文件,可以通過WindowManager::loadWindowLayout函數載入此文件。此函數為你創建所有的窗口并返回一個指向根窗口的指針。調用setGUISheet設置GUI的根窗口的時候用此指針再適合不過了。
所以,首先我們需要一個布局文件。下面這個XML文件所描述的窗口和我們上面用C++創建的窗口是一樣的:
14<guilayout>
15<windowtype=”DefaultWindow”name=”root”>
16<windowtype=”TaharezLook/FrameWindow”name=”testWindow”>
17<propertyname=”UnifiedPosition”value=”{
{0.25,0},{0.25,0}}”>
18<propertyname=”UnifiedSize”value=”{
{0.5,0},{0.5,0}}”>
19<propertyname=”Text”value=”HelloWorld!”>
20</property></property></property></window>
21</window>
22</guilayout>
Window元素的屬性和WindowManager::createWindow函數的參數是一一對應的。參見上面討論過的createWindow函數。
鑲嵌的Window元素用來表明窗口的父子關系。注意:在一個布局文件中,你僅可以擁有一個“根”級別的窗口,這也是通常情況下把DefaultWindow用作根窗口的另一個原因。
Property元素是用來設置當前窗口的屬性的。每種窗口/控件類都有很多屬性,而且每個類都從它的父類中繼承所有的屬性??梢栽谶@里查看所有硬編碼屬性以及它們的格式。由于“Falagard”蒙皮(’Falagard’skins)可以創建自己的屬性,你所使用的窗口可能會有更多的屬性—-對于那些“軟編碼”屬性,你需要參閱你所使用的蒙皮的相關文檔(參看樣品蒙皮TaharezLook和WindowsLook)。
如果保存此布局文件為“test.layout”,你可以按如下方法加載并設置GUI根窗口:
23usingnamespaceCEGUI;
24Window*myRoot=WindowManager::getSingleton().loadWindowLayout(
25“test.layout”);
26System::getSingleton().setGUISheet(myRoot);
編譯運行后得到的結果和前面用C++寫的程序是一樣的。不過,現在你可以輕松修改、增強GUI布局而不用修改、重新編譯代碼啦。
cegui5輸入輸出入門
CEGUI輸入處理簡介
CEGUI不會自動捕獲任何的用戶輸入,由程序決定CEGUI需要處理哪些輸入.這意味著:每當產生案件或者鼠標移動等消息時,你就得把它門傳遞給CEGUI,盡管這看起來很奇怪,這其實也給你更多的控制權,我們并沒有把所有的輸入綁定到特定的系統,你可以篩選傳遞CEGUI需要獲得的輸入.
傳遞你的輸入
我們創建了一個接口用來向CEGUI傳遞輸入信息.它由CEGUI::System類的一組成員函數組成——–對于每種基本的輸入類型都有一個函數與之對應
booliniectMousemove(floatdelta_x,floatdelta_y);
boolinjectMousePosition(floatx_pos,floaty_pos);
boolinjectMouseLeaves(void);
boolinjectMouseButtonDown(MouseButtonbutton);
boolinjectMouseButtonUp(MouseButtonbutton);
boolinjectKeyDown(unitkey_code);
boolinjectKeyUp(unitkey_code);
boolinjectChar(utf32code_point);
boolinjectMouseWheelChange(floatdelta);
boolinjectTimePulse(floattimeElapsed);
是的,看起來很多,你可能注意到有點重復了,比如”mousemove”和”mouseposition”有點重復.
“keydown”和”char”等.其實這么做是為了方便使用,對于鼠標,你可以傳遞相對位移(injectMouseMove)或絕對坐標(injectMousePosition),具體選擇哪種很大程度上取決于使用的輸入庫支持的類型.對于按鍵,你可以傳遞按下.抬起(injectKeyDown/injectKeyUp)以及字符(injectChar)消息.這樣做有2個原因:第一,不是所有的按鍵都產生字符消息(比如shiftalt)等等;第2,允許你自定義按鍵映射和自動重復按鍵(CEGUI目前不提供那些函數)
另外要說明的是函數的布爾返回值.他是用來告訴程序CEGUI是否處理了此消息.如果返回false,說明CEGUI沒有處理此消息,
此時你的程序需要做另外一些處理.
那些函數是用來干什么的
下面,我們將要簡要的討論每個函數的作用,它需要的參數,它用輸入做了什么。
1boolinjectMouseMove(floatdelta_x,floatdelta_y)
此函數用來傳遞鼠標移動信息。參數“delta_x”和“delta_y”分別用來指明鼠標在X軸和Y軸上所移動的位移(有方向)。這將導致鼠標做相應的移動(具體移動的大小可以通過CEGUI::System::setMouseMoveScaling設置比例因子改變)。如果你用此函數,基本上就不需要使用injectMousePosition函數了。
2boolinjectMousePosition(floatx_pos,floaty_pos)
此函數用來傳遞鼠標當前的絕對坐標。參數“x_pos”和“y_pos”用來指明鼠標的絕對坐標,坐標系的原點(0,0)在CEGUI窗口的左上角(所以,在窗口模式下,原點在窗口左上角而不是整個桌面的左上角)。這將把鼠標移動到新的位置。如果你用此函數,基本上就不需要使用injectMouseMove函數了。
3boolinjectMouseLeaves(void)
此函數用來告訴系統鼠標已經離開程序窗口了。在窗口模式下,此方法很有用。
4boolinjectMouseButtonDown(MouseButtonbutton)
此函數用來告訴系統某個鼠標按鍵被按下了。參數“button”可以取如下所示的CEGUI::MouseButton枚舉值:
5enumMouseButton
6{
7LeftButton,
8RightButton,
9MiddleButton,
10X1Button,
11X2Button,
12MouseButtonCount,
13NoButton
14};
如果你的輸入庫和上面的不吻合,你必須自己轉化。另外,要注意:NoButton的值不是0。
15boolinjectMouseButtonUp(MouseButtonbutton)
此函數用來告訴系統某個鼠標按鍵被釋放了。它的參數和injectMouseButtonDown是一樣的。
16boolinjectKeyDown(uintkey_code)
此函數用來告訴系統某個按鍵被按下了。它的參數“key_code”是那個按鍵的掃描碼(不是ASCII碼或其他的字符編碼)。所有的掃描碼在CEGUI::Key::Scan枚舉變量中有定義。微軟的DirectInput庫輸出的掃描碼和我們的是一樣的,如果使用其他的庫,你可能需要做一些轉換。目前看來,并不需要傳遞所有的按鍵按下/釋放消息,一般需要這些消息的是:backspace,delete,回車,shift以及方向箭頭按鍵。
目前沒有實現按鍵到字符的映射,也沒有提供自動重復按鍵的函數(這些也許在以后會實現)。如果你需要自動重復按鍵功能,你可以使用輸入庫提供的函數或者自己編碼實現。你肯定需要輸入字符,請看下面的injectChar函數。
17boolinjectKeyUp(uintkey_code)
此函數用來告訴系統某個按鍵被釋放了。和injectKeyDown的參數一樣,“key_code”是按鍵的掃描碼。
18boolinjectChar(utf32code_point)
此函數用來告訴系統一個字符按鍵被按下。在輸入文本的時候,你需要用此函數。參數“code_point”是一個字符的UnicodeUTF32編碼(欲了解Unicode請參看此Unicode網站)。怎樣獲得這個值取決于你所使用的輸入庫。對于ASCII字符,你只需直接以ASCII碼的形式傳遞給它即可,因為Unicode碼和ASCII碼的0到127部分是相同的。對于其他字符,你使用的輸入庫應該會有相關的API(比如:通過微軟的Windows消息泵可以獲得字符的UTF32編碼),具體怎么做不屬于本教程的范圍。
19boolinjectMouseWheelChange(floatdelta)
此函數用來告訴系統鼠標滾輪的使用情況。正數表示向前滾動(遠離用戶方向),負數表示向后滾動(接近用戶方向)。
20boolinjectTimePulse(floattimeElapsed)
此函數用來告訴系統相關時間信息。參數“timeElapsed”表示自上次調用此函數或運行CEGUI以來所經過的秒數。此函數越來越重要了,它被用來控制控件的消失,為工具提示、菜單以及鼠標按鍵的自動重復提供計時等。
想看一些具體的例子,這里提供兩個:
*我們在wiki上有一些很牛的例子
oUsingCEGUIwithSDLandOpenGL
oUsingCEGUIwithProducerandOpenGL
*使用示例框架代碼寫成的例子被保存在cegui_mk2/Samples/common/src:
oWin32AppHelper.cpp–containsawindowsmessageprocedureinjecting
mouseandcharacterinputsintoCEGUI,andusingDirectInput
forkeyboardupanddownmessages.
oCEGuiOgreBaseApplication.cpp–containsanexampleOgre::FrameListener
classwhichtakesinputsgeneratedbytheOISLibraryand
injectstheseintoCEGUI.
oCEGuiOpenGLBaseApplication.cpp–registerscallbackfunctionswithglut
toprocessinputs,andalsoshowstheuseofakey
translationtable.
此外,使用Irrlicht的同學可以使用Irrlicht自帶的eventpusher—-每當一個輸入產生的時候你可以使用IrrlichtRenderer的OnEvent函數處理它(你只需用injectTimePulse處理時間)。
cegui6統一度量系統使用指南
注意:此教程僅適用于CEGUI>=0.4.0
統一度量系統使得我們可以用相對部分和絕對部分共同來表示一個坐標或大小。這給窗口布局帶來了極大的方便。比如:你可以用相對尺寸來表示高度,使用絕對大小表示寬度,或者混合使用。
統一度量系統共有三種形式
*UDim:簡單的一維
*UVector2:由兩個UDim組成的二維向量
*URect:用四個UDim表示一個矩形,依次為:左,上,右,下
UDim
1格式為:{scale,offset}
2例如:{1,0}
父窗口的值乘以“scale”然后加上offset就是最后的結果(單位都是像素)。例如:假如上面的例子是窗口的UnifiedWidth屬性值,我們將得到和其父窗口一樣寬的窗口。
另一個例子:
{0.5,25}
這將使得到的窗口寬度為其父窗口的一半加上25像素。
使用單一UDim作為其值的屬性有:
*UnifiedXPosition
*UnifiedYPosition
*UnifiedWidth
*UnifiedHeight
UVector2
UVector2是用來表示位置和大小的。
3格式為:{
{x-scale,x-offset},{y-scale,y-offset}}
4例如:{
{1,0},{1,0}}
UVector2中包含的兩個UDim很像。還是用例子說明吧:假如上面的例子代表窗口的UnifiedSize屬性,我們將得到和它的父窗口一樣大小的窗口。
5{
{1,0},{0,100}}
上例將產生一個和其父窗口一樣寬,但是高度固定為100像素的窗口。
使用Uvector2作為其值的屬性有:
*UnifiedPosition
*UnifiedSize
*UnifiedMinSize
*UnifiedMaxSize
URect
最后的一種是URect。它有點特殊,它定義了左,上,右,下四個坐標,而不是大小或位置。由于參數很多,我將用“ls”代替“left-scale”,用“to”代替“top-offset”等等。
6格式為:{
{ls,lo},{ts,to},{rs,ro},{bs,bo}}
7例如:{
{0,0},{0,0},{1,0},{1,0}}
上述代碼是DefaultWindow類型窗口的默認矩形。它將覆蓋其父窗口的整個區域。只有一個屬性使用URect值—-UnifiedAreaRect。
我們定義矩形區域而不是其大小的做法是很聰明的。比如:假如我們想使一個窗口覆蓋它的父窗口,但要為父窗口的四邊分別留出10像素的大小,代碼可以這樣寫:
8{
{0,10},{0,10},{1,-10},{1,-10}}
此例可以看出,絕對部分可以取負數。
XML中的應用舉例
9<propertyname=”UnifiedPosition”value=”{
{0.1,10},{1.0,-30}}”>
10</property>
X-position:父窗口寬度的10%+10像素
Y-position:父窗口的高度–30像素
11<propertyname=”UnifiedSize”value=”{
{0.6,5},{0.3,20}}”>
12</property>
Width:父窗口寬度的60%+5像素
Height:父窗口高度的30%+20像素
13<propertyname=”UnifiedXPosition”value=”{0.25,-5}”>
14</property>
X-position:父窗口寬度的25%–5像素
15<propertyname=”UnifiedAreaRect”value=”{
{0.1,0},{0.1,0},{0.9,0},{0.9,0}}”>
16</property>
X-position:父窗口寬度的10%
Y-position:父窗口高度的10%
Width:父窗口寬度的80%
Height:父窗口高度的80%
cegui7在CEGUI中使用Lua腳本入門
CEGUI所使用的腳本是基于Lua5.0.2和tolua++1.06pre2-1的.
界面的編寫很大一部分可以通過腳本來實現.我們可以修改腳本而不必重新編譯整個程序,
這就為我們省去了好多時間去設計界面.
目前的Lua腳本模塊仍然處于初期的開發階段。它支持絕大多數的內核系統、基層的窗口類,不過,對于某些特殊的控件目前只能通過屬性系統(propertiessystem)來設置。
初始化
Lua腳本模塊囊括了所有的管理類(managerclasses),所以可以通過Lua腳本對CEGUI進行簡單的初始化.例如:
#include“CEGUILua.h”
1CEGUI::YourRendererOfChoice*renderer=newYourRendererOfChoice;
2CEGUI::LuaScriptModule*script_module=newCEGUI::LuaScriptModule();
3
4//第二個參數設置xml解析器,0代表默認解析器
5newCEGUI::System(renderer,0,script_module);
現在CEGUI::System已經被創建,腳本模塊也被指定了。此時,LuaScriptModule的構造函數自動為我們創建了一個lua_State。你也可以傳遞一個lua_State*到LuaScriptModule的構造函數中來使用自己的lua_State。
如果你在初始化腳本中用到自定義函數,你就需要這么做。代碼如下:
6…
7lua_State*s=your_lua_state;
8CEGUI::LuaScriptModule*script_module=newCEGUI::LuaScriptModule(s);
9…
初始化/退出腳本
CEGUI支持一個配置文件。它的文件名是CEGUI::System的構造函數的一個可選參數。默認為“cegui.config”。
通過設置此配置文件,你可以控制在系統創建和銷毀的時候是否執行一個腳本。配置文件的內容類似這樣:
10<?xmlversion=”1.0″?>
11<CEGUIConfig
12InitScript=”../datafiles/scripts/init_script.lua”
13TerminateScript=”../datafiles/scripts/exit_script.lua”
14/>
init_script.lua是在系統初始化時候將要被執行的Lua腳本文件。內容可以是這樣:
15—獲取CEGUIsingletons
16locallogger=CEGUI.Logger:getSingleton()
17logger:logEvent(“>>>Initscriptsayshello”)
18–logger:setLoggingLevel(CEGUI.Informative)
19
20—為我們要使用的singletons創建相應的局部變量(非必須)
21localsystem=CEGUI.System:getSingleton()
22localfontman=CEGUI.FontManager:getSingleton()
23localschememan=CEGUI.SchemeManager:getSingleton()
24
25—載入schemes
26schememan:loadScheme(“../datafiles/schemes/TaharezLook.scheme”)
27schememan:loadScheme(“../datafiles/schemes/WindowsLook.scheme”)
28
29—載入默認字體
30localfont=fontman:createFont(“../datafiles/fonts/Commonwealth-10.font”)
31
32—設置默認鼠標光標
33system:setDefaultMouseCursor(“TaharezLook”,”MouseArrow”)
34
35logger:logEvent(“<<<Initscriptsaysgoodbye”)
并不一定要同時提供初始化和退出腳本,但是,假如你在初始化腳本中申請了全局使用的存儲空間,那你就要在退出腳本中釋放它(或者在其它合適的地方)。
cegui8Lua消息處理入門
把GUI的消息處理從代碼中分離出來,并交給lua腳本處理,這樣可以給你的界面帶來很大的靈活性.GUI的相關地東西可以在測試期間很輕松的修改.Lua中的負責處理消息的東西其實只不過是普普通通的只帶一個參數的Lua函數而已.若想用它作事件處理函數,你必須先在系統中注冊它.所以除非你在初始化腳本中載入他們,你必須在處理相應事件之前載入相關腳本文件.
載入腳本文件
有2種載入腳本文件的方法:使用c++代碼或者在初始化腳本中使用Lua代碼,由于Lua函數和相應的c++函數一一對應,這2種方法看起來很像.
CEGUI::System::executeScriptFile(constCEGUI::String&filename,constCEGUI::String&resourceGroup=””);
顯然這個函數有兩個參數:文件名和資源組。大多數情況下,可以不用管最后一個參數。
通過CEGUI指定的Lua腳本模塊調用此函數就可以執行指定的Lua腳本文件。這意味著:你的程序可以訪問腳本中文件定義的函數等所有東西了,當然,被定義為局部范圍的除外。
例如,用C++可以這么寫:
1CEGUI::System::getSingleton().executeScriptFile(“../datafiles/scripts/guiscript.lua”);
如果有錯誤產生,它會拋出一個異常。
用Lua可以這么寫:
2CEGUI.System:getSingleton():executeScriptFile(“../datafiles/scripts/guiscript.lua”)
腳本文件中的全局代碼也將被執行,所以要注意對每次執行進行必要的處理(使用一個計數器fx)。
注冊事件到Lua函數
既然我們已經載入了腳本文件,下一步就可以綁定事件到腳本處理函數上了.
綁定Lua函數的函數與綁定C++函數的函數名稱不同。
3Event::ConnectionsubscribeScriptedEvent(constString&name,
4constString&subscriber_name);
參數name是你要綁定的事件。參數subscriber_name為處理此事件的Lua函數的函數名。
調用完此函數后,指定的Lua函數就將成為那個事件的處理函數。而且它運行起來和C++版本的函數幾乎一模一樣(當然,不同的是:它是Lua腳本)。
如下是綁定PushButton單擊事件到一個Lua函數上的代碼片段:
5CEGUI::PushButton*pb=(CEGUI::PushButton*)CEGUI::WindowManager::getSingleton().createWindow(“TaharezLook/Button”,”lua_powered_button”);
6pb->setSize(CEGUI::Size(0.1f,0.1f));
7pb->setPosition(CEGUI::Point(0.1f,0.1f));
8pb->subscribeScriptedEvent(“Clicked”,”luabtn_clicked”);
9CEGUI::System::getSingleton().getGUISheet()->addChildWindow(pb);
這段代碼將創建一個簡單的TaharezLook按鈕,把它的Clicked事件綁定到Lua函數luabtn_clicked中,然后把它添加到當前的GUI。
現在,我們看一下那個Lua事件處理函數:
10functionluabtn_clicked(e)
11localwe=CEGUI.toWindowEventArgs(e)
12we.window:setText(“handledfromLua”);
13end
它使得當按鈕被按下時,它的文本會變成“handledfromLua”。
我們使用了一個公用的函數:
14CEGUI.toWindowEventArgs(e)
從它的名字可以看出:它把EventArgs參數轉換為WindowEventArgs類型。其他的EventArgs類型也有類似的轉換函數。
在Layout文件中注冊Lua事件處理函數
在Layout文件中綁定用Lua寫的事件處理函數是很簡單的??聪逻@個例子吧:
15<?xmlversion=”1.0″?>
16<GUILayout>
17<WindowType=”TaharezLook/Button”Name=”lua_powered_button”>
18<PropertyName=”Width”Value=”0.1″/>
19<PropertyName=”Height”Value=”0.1″/>
20<PropertyName=”XPosition”Value=”0.1″/>
21<PropertyName=”YPosition”Value=”0.1″/>
22<EventName=”Clicked”Function=”luabtn_clicked”/>
23</Window>
24</GUILayout>
這個簡單的layout文件所做的事和上面的C++代碼是一樣的。
cegui9編寫CEGUI腳本入門
本教程所列的代碼是Lua腳本,它用到了CEGUI自0.4版本起所綁定的CEGUILua模塊。這些代碼片段可能沒有多少實際用途,但它們足以展示CEGUI和Lua結合起來使用的可能性。
更改記錄級別
locallogger=CEGUI.Logger:getSingleton()–獲取logger
locallvl=logger.getLoggingLevel()–獲取記錄級別
iflvl<CEGUI.Insanethen
logger:setLoggingLevel(lvl+1)
end
此代碼:每次增加記錄級別一個等級直到到達Insane級別.
載入一個Scheme
CEGUI.SchemeManager:getSingleton():loadScheme(“../datafiles/scheme/TaharezLook.scheme”)
此代碼:載入了TaharezLook.scheme.
簡單的界面
1—創建GUIsheet
2localsheet=CEGUI.WindowManager:getSingleton():createWindow(
3“DefaultGUISheet”,”root”);
4CEGUI.System:getSingleton():setGUISheet(sheet)—然后,把它附著到系統中
5—創建一個FrameWindow
6localfw=CEGUI.WindowManager:getSingleton():createWindow(
7“TaharezLook/FrameWindow”,”framewnd”);
8—把它附著到sheet上
9sheet:addChildWindow(fw)
10
11—設置它的大小和位置
12localsz=CEGUI.Size(0.5,0.5)
13localpos=CEGUI.Point(0.2,0.1)
14fw:setSize(sz)
15fw:setPosition(pos)
16—禁止用戶改變大小
17fw:setProperty(“SizingEnabled”,”False”)
18
19—使關閉按鈕生效
20fw:subscribeEvent(“CloseClicked”,”fwCloseClicked”)
21
22—CloseClicked事件的處理函數
23functionfwCloseClicked(eventArgs)
24localwe=CEGUI.toWindowEventArgs(eventArgs)
25CEGUI.WindowManager:getSingleton():destroyWindow(we.window)—銷毀frame窗口
26end
此代碼:創建一個GUISheet,把它附著到System上。然后,創建一個FrameWindow,設置它的大小和位置,禁用更改大小屬性并為CloseClicked事件綁定了事件處理函數。
類型轉換的另一種方法
27—CloseClicked事件的處理函數
28functionfwCloseClicked(eventArgs)
29localwe=tolua.cast(eventArgs,”CEGUI::WindowEventArgs”)
30CEGUI.WindowManager:getSingleton():destroyWindow(we.window)—銷毀frame窗口
31end
此代碼:展示了把EventArgs對象轉換成WindowEventArgs類型的另一種方法。
載入一個layout
32localw=CEGUI.WindowManager:getSingleton():loadWindowLayout(
33“../datafiles/layouts/test.layout”)
34CEGUI.System:getSingleton():getGUISheet():addChildWindow(w)
此代碼:載入了一個layout并把返回的窗口添加到當前的GUISheet中。
彈出菜單
35—我們將多次使用WindowManager對象
36localwmgr=CEGUI.WindowManager:getSingleton()
37
38—設置菜單
39localbar=wmgr:createWindow(“WindowsLook/Menubar”,”the_menu_bar”)
40bar:setSize(CEGUI.Size(1,0.1))
41CEGUI.System:getSingleton():getGUISheet():addChildWindow(bar)
42
43—添加一個菜單項
44localitem=wmgr:createWindow(“WindowsLook/MenubarItem”,”the_menu_bar_item”)
45item:setText(“Baritem”)
46bar:addChildWindow(item)
47
48—添加一個彈出菜單到菜單項中
49localpop=wmgr:createWindow(“WindowsLook/PopupMenu”,”the_popup_menu”)
50item:addChildWindow(pop)
51
52—添加一些菜單項到彈出菜單中
53item=wmgr:createWindow(“WindowsLook/PopupMenuItem”,”the_popup_menu_item_1″)
54item:setText(“Popupitem1”)
55pop:addChildWindow(item)
56
57item=wmgr:createWindow(“WindowsLook/PopupMenuItem”,”the_popup_menu_item_2″)
58item:setText(“Popupitem2”)
59pop:addChildWindow(item)
此代碼:創建了一個簡單的菜單,并添加了一個包含兩個子菜單的彈出式菜單到它上面。
更多精彩內容,請見:http://www.16boke.com
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
CAD 2020如何將高版本換成低版本?有兩種方法可以把高版本的cad圖紙轉換成低版本的———— : 1,請安裝了高版本的朋友打開這個文件,保存為低版本文件。2.尋找 "CAD版本轉換器AcmeCADConv:[ACMECADCconvertor _ cn.rar版]。cad怎樣打開為高版本的cad文件?較低版本的AutoCAD打開較高版本的CAD文件如下::。1.第一步:首先在較高版本中打開要用...
冰糖葫蘆廣場舞原唱?馮曉泉?!侗呛J》是一首由張和平和杜鵬作詞,馮曉泉作曲,馮曉泉演唱的歌曲,于1995年1月1日發行。包括在專輯《龍鳳金歌榜VOL.9》中。歌詞:都說糖葫蘆是酸的,酸中包裹著甜。都說糖葫蘆是甜的,但是表現出來的是里面的酸。糖葫蘆可以和竹簽一起穿,象征幸福和團圓,把幸福和團圓聯系在一起,沒有煩惱和煩惱。如果你站得高,你會看得遠。如果你面對蒼山的召喚,你會怒而心寬,你會年輕二十歲。...
北京哪里可以辦理農業銀行卡?農業銀行可以在以下網點辦理農業銀行八里橋支行京通高速惠村站北管莊鄉綜合樓二樓農業銀行國門支行首都機場2號航站樓一樓農行會展中心支行曙光西里6號院時代國際大廈一樓農業銀行機場支行順平路556號北京哪個地鐵站有農行?地鐵西直門站附近的農業銀行有:-農業銀行ATM距離西直門地鐵站762米,在北京西城區元沃天地地鐵商城地下一層??蓳Q乘地鐵4號線大興線19、107、65、45、特...