OpenGL GUI教程(一)
作者:Ionware
譯者:akinggw
歡迎來到我的GUI系列文章的第一篇。我從一個非常高的角度更新了他們,這樣是為了便于你喜歡上她並且能很快明白。
她是一個OPENGL GUI,只需要OPENGL去渲染她的組件和建立紋理/材質,但從某種意義上說她並不依賴與OPENGL
目錄
l 簡介
l 類定義和結構
l 畫一個東東
l 處理輸入
l 下載
簡介
什麼是GUI?圖形用戶界面。正確,還有什麼?好的,讓我們看一下標準的WINDOWS。她像什麼?就像一個帶邊框,顏色和紋理的簡單的多邊形。因此,假設我們的GUI也將是一個2D多邊形(四邊形)。那我們需要怎樣做呢?讓我們看一下。
類定義和結構
我們的第一個類,是的,CGUIElement,是其它控制的基礎。我們將以後為它添加更多的功能。讓我們看一下這個類:
class CGUIElement: public CXMLResource,public CdoubleList<CGUIElement *>
{
CREATOR(CGUI);
CREATOR(CGUIBorder);
Public:
CGUIElement();
Virtual ~CGUIElement();
Virtual void Initialize();
Virtual int Create(CGUIElement *pParent,tRect WidgetRect,Ctexture *pTexture = NULL,Cmaterial *pMaterial = NULL,bool bBorder = false);
Virtual int LoadXML(TiXmlNode *pDateNode,Cstring strFilename);
Virtual int SaveXML(TIXmlNode *pDateNode,Cstring strFilename);
Virtual void Draw();
Virtual void Destroy();
Virtual void ProcessMessages();
Virtual void ProcessMessage(tGUIMessage& Message);
Virtual int Resize(tRect& NewRect);
Virtual int OnKeyDown(UINT uiKeyCode);
Virtual int OnKeyUp(UINT uiKeyCode);
Virtual int OnMove(UINT x,UINT y);
Virtual int OnMouseMove(UINT x,UINT y);
Virtual int OnLMouseDown(UINT x, UINT y);
Virtual int OnLMouseUp(UINT x, UINT y);
Virtual int OnRMouseDown(UINT x,UINT y);
Virtual int OnRMouseUp(UINT x,UINT y);
UINT GetWidth();
Void SetWidth(UINT uiWidth);
UINT GetHeight();
Void Setheight(UINT uiHeight);
CGUIElement *GetChild(UINT uiIndex);
CGUIElement *GetChild(eGUIControlType eWidgetType);
CGUIElement *GetChild(TiXmlElement *pXMLElement);
UINT GetChildCount();
Void RemoveChild(CGUIElement *pChild);
Void HideSiblings(int iDeep = -1);
Void ShowSiblings(int iDeep = -1);
Void SetZOrder(UINT uiZOrder);
UINT GetZOrder();
Bool Visible();
void Hide();
void Show();
CGUIElement *GetParent();
Void Setparent(CGUIElement *pParent);
Void SetTexture(Ctexture *pTexture);
Ctexture *GetTexture();
Void SetMaterial(Cmaterial *pMaterial);
Cmaterial *GetMaterial();
Void SetTexCoord(UINT uiIndex,float U,float V);
Tvertex2f& GetTexCoord(UINT index);
CGUI *GetGUI();
Void SetRect(tRect& NewRect);
TRect& GetRect();
Void SetGUI(CGUI *pGUI);
EGUIControlType& GetType();
Void SetType(eGUIControlType eWidgetType);
Void SetFlag(eGUIFlag eFlag,bool bSet);
Bool IsFlagSet(eGUIFlag eFlag);
Bool IsChild(CGUIElement *pElement);
Bool IsAutoCalc();
Void SetAutoCalc(bool bAutoCalc);
Virtual bool IsOfType(eEntityType eType);
Cstring GetElementType(); #ifdef GUI_USE_ACTIVE_INACTIVE bool IsActive() { return m_bActive; }; void Activate() { m_bActive = true;}; void Deactivate() {m_bActive = false;};#endif protected: #ifndef GUI_USE_ACTIVE_INACTIVE Cmaterial *m_pMaterial; //組件的材質指針 #elif COLORREF m_ActiveColor; //材質活動的顏色 COLORREF m_InactiveColor; //材質靜止的顏色 Bool m_bActive; //材質是活動或靜止 #endif //組件的關鍵參數 eGUIControlType m_eControlType; //組件的類型 bool m_bAutoCalc; //自動計算標志:用于很多方面 CGUIElement *m_pParent; //父親組件 CGUI *m_pGUI; //根GUI DWORD m_dwFlags; //組件標志 Ctexture *m_pTexture; //組件的紋理指針 Tvertex2fm_texCoord[4]; //組件的紋理坐標 Bool m_bVisible; //組件的可視標志
};
這段代碼顯示的結構如下:
http://openglgui.sourceforge.net/images/gui_tut1_img1.jpg
是的,這是一個非常大的類,她是我們一切的基礎,因此,現在我們看一下她的功能函數。
首先,我們需要初始化一個組件,這個完全可以在構造函數中完成,但是我選擇在Initialize()函數中完成她。
正如你所看到的,我們有自己的消息處理類,因此每個類都有自己的消息處理函數ProcessMessages()在每次畫的時候處理它,並且尋找與她相關的消息。例如,按下一個按鈕後會出現一個下拉菜單,你是否會選擇她其中的一個選項。
每個組件也有一個導入/保存函數,但是並不需要每次都重寫她。相反,我們使用一個通用的類去保存她的組件參數,然後在根結點時保存整棵樹的參數。同樣,我們也有自己的鍵盤/鼠標處理函數。
整個GUI的結構如下:
http://openglgui.sourceforge.net/images/gui_tut1_img2.jpg
|