青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

【ZT】DXUTGUI控件的定制


From: http://blog.csdn.net/foruok/ 


最近在研究DXUT自帶的控件庫,按照SDK及例子做了些試驗,總是那個固定的樣子(可以看DXSDK中的例子,就是哪種效果),讓人一眼就看出來界面是利用DXUTGUI實現的。我想要做出自己的效果,看來必須定制。

    定制包含兩個方面,整個控件庫風格的定制和特定控件實例本身的定制。

    我們先說整個UI風格的定制。

    我是從SDK的CUSTOMUI入手學習DXUT的。

    這個例子聲明了一個全局的對話框資源管理對象CDXUTDialogResourceManager g_DialogResourceManager,然后用它分別初始化三個對話框。以SampleUI對話框為例,初始化語句在InitApp函數中: g_SamleUI.Init(&g_DialogResourceManager)。對Init函數的調用只有一個參數,另一個是默認的 bRegisterDialog=true。

    DXUT實現了按鈕、列表框、可選按鈕、編輯框等控件。一開始我以為控件是直接畫出來的(這種感覺太愚蠢了),后來想想應當是用的紋理貼圖。但是怎么也沒有找到它所用的紋理文件在哪里,看來必須閱讀DXUTGUI的源碼了。

    從Init函數入手來研究DXUTGUI的資源管理是個不錯的選擇。我一路跟進去,發現按照示例程序那樣初始化對話框時,會從內存中加載“皮膚”紋理。 DXUTGUI所用的內存紋理資源是DDS格式的,保存在DXUTRes.cpp的g_DXUTGUITextureSrcData數組內。這就是它的奧秘所在了。

    將這個紋理保存成bmp圖片(256X256),就可以看到DXUTGUI控件的資源了。

    有了這個發現,我們就可以實現自己的風格了。只需兩步:

    (1)仿照DXUTGUI自帶的皮膚紋理制作自己的圖片
    (2)在初始化對話框時選擇三個參數的Init函數,指定紋理圖片的路徑。

    需要注意的是,我們所做的圖片必須與DXUTGUI使用的圖片規格一樣,包括各種元素所對應的紋理區域等等,否則可能會一團糟。當然還有一個辦法可以不和 DXUTGUI的圖片規格保持一致:修改CDXUTDialog::InitDefaultElements函數。

    研究InitDefaultElements函數可以了解DXUTGUI是怎么使用紋理皮膚的,有助于我們實現自己的皮膚。

DXUTGUI提供的默認控件已經實現了透明效果和類似色彩鍵的效果。在D3D中沒有直接的色彩鍵(direct draw中有)功能,不過可以利用alpha通道實現類似的效果,只是需要圖片具有alpha通道。

    DXUTGUI的控件紋理正是這樣實現的,用photoshop打開保存下來的紋理圖片,可以看到其alpha通道的圖片。

    要在D3D9中實現透明和顏色過濾功能,需要兩個步驟。

    (1)定義FVF結構體,包含頂點顏色域。定義FVF標記,使其包含D3DFVF_DIFFUSE。

    struct CustomVertext{
        float x,y,z,h;
        DWORD color;
    };

    #define CUSTOMFVF   D3DFVF_XYZRHW | D3DFVF_DIFFUSE


    (2)設置渲染狀態:

    pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
    pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
    pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );   
    pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
    pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );


    透明效果的實現是通過頂點顏色的alpha值(0完全透明,255不透明)實現的,而顏色過濾是通過紋理的alpha通道實現的,兩者的乘積可以實現“透明+過濾”效果。這樣就可以實現不規則且透明的控件。

    對應在DXUTGUI中,如果要設置某一個控件的透明度,可以調用該控件的GetElement函數,獲取CDXUTElement類型的指針,調用其SetTexture函數實現。

    要統一設置某一類控件的透明度,可以調用CDXUTDialog::GetDefaultElement獲取該類控件的分子對象的指針,修改其TextureColor成員的alpha通道(或者調用SetTexture函數)。

    知道了DXUTGUI如何實現上述效果,我們就有了定制UI的基礎。通過提供具有alpha通道的圖片給DXUTGUI使用,就可以隨心所欲的實現各種效果的控件了。但如何讓DXUTGUI為某一個控件(如一個按鈕)使用我們自己的圖片,還需要做進一步的挖掘和實現。


定制控件

     DXUTGUI的控件庫默認使用內置的紋理資源,這個紋理資源可以在CDXUTDialog的Init函數中指定為我們自己的紋理資源(通常可以用一個圖片文件來替代)。

    研究CDXUTDialog的InitDefaultElements函數可以發現,DXUTGUI為每種控件定義了若干元素,這些元素保存在 m_DefaultElements數組中。當增加一個新的控件時,比較控件類型,將該類型的元素集從DefaultElements取出,傳遞給該控件,該控件生成自己的元素實例并保存起來。

    我們發現紋理資源保存在CDXUTDialogResourceManager的成員變量m_TextureCache中。m_TextureCache 是一個動態數組,可以保存任意的紋理資源,如一個按鈕的圖片紋理,一個列表框的背景紋理等。只需要調用CDXUTDialg::SetTexture函數,指定一個ID和紋理文件名即可。

    紋理有了保存的地方,接下來只需要讓控件使用我們自己的紋理就可以進行定制了。而控件的定制分為三類:單個控件的定制、一類控件的定制、生成新控件類型。下面一一說明怎么來實現。
 

    一、單個控件定制

    單個控件的定制比較簡單,以按鈕為例,需要三步:

    (1)CDXUTDialog::AddButton生成按鈕pBtn
    (2)CDXUTDialog::SetTexture,生成該按鈕的紋理,記錄紋理序號nTexture
    (3)pBtn->GetElement獲取CDXUTElement指針pElem,pElem->SetTexture修改該控件所用紋理為nTexture。

    上面的定制受限于DXUTGUI,需要根據其所實現的控件的渲染方法來生成自己的紋理資源,還要查看InitDefaultElements來決定怎么調用CDXUTElement::SetTexture和CDXUTElement::SetFont。

 

    二、單類控件的定制

    某一類控件的定制需要更改該類控件的默認元素,這個可以通過CDXUTDialog::SetDefaultElement來實現。需要兩步完成:

    (1)CDXUTDialog::SetTexture,生成該類控件的紋理,記錄紋理序號nTexture
    (2)CDXUTDialog::GetDefaultElement或者默認元素對象的指針pElem,然后pElem->SetTexture修改。

    第(2)步也還有另一種實現方法。聲明CDXUTElement對象,設置其成員,然后調用CDXUTDialog:: SetDefaultElement,改寫初始化時生成的默認元素集。無論怎樣,都需要了解InitDefaultElements函數中做了什么。

 

    三、生成新控件類型

    生成新控件并使用定制的紋理,需要以下幾步:

    (1)實現控件類
    (2)加載資源
    (3)為新類型控件生成默認元素集
    (4)生成控件實例,添加到對話框

    我們不改變DXUT自己的文件,一切都在我們自己的文件中實現。

    (1)DXUTGUI提供的控件不一定能滿足我們需要,有時候需要自己實現新的控件,如圖片按鈕。我們可以從CDXUTControl派生,也可以從某個特定的控件類派生。下面我們以圖片按鈕的實現為例來說明,先看代碼。
class CDXUTImageButton : public CDXUTButton
{
public:
    CDXUTImageButton(CDXUTDialog *pDialog = NULL ):CDXUTButton(pDialog)
    {
        m_Type = (DXUT_CONTROL_TYPE)(DXUT_CONTROL_SCROLLBAR + 1);
    };
    ~CDXUTImageButton(void)...{};
    virtual void Render( float fElapsedTime )
    {    
int nOffsetX = 0;
    int nOffsetY = 0;
    DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
    int iIndex = 0;
    if( m_bVisible == false )
    {
        iState = DXUT_STATE_HIDDEN;
    }
    else if( m_bEnabled == false )
    {
        iState = DXUT_STATE_DISABLED;
        iIndex = 2;
    }
    else if( m_bPressed )
    {
        iState = DXUT_STATE_PRESSED;
        iIndex = 1;
    }
    else if( m_bMouseOver )
    {
        iState = DXUT_STATE_MOUSEOVER;
        iIndex = 3;
    }
    else if( m_bHasFocus )
    {
        iState = DXUT_STATE_FOCUS;
        iIndex = 3;
    }
    // Main button
    CDXUTElement *pElement = m_Elements.GetAt( iIndex );
    float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
    // Blend current color
    pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
    m_pDialog->DrawSprite( pElement, &m_rcBoundingBox, 0.8f );
};

    我們需要為CDXUTImageButton指定一個控件類型,取DXUT_CONTROL_SCROLLBAR + 1。同時改寫CDXUTButton的Render函數,依據按鈕狀態取不同的紋理元素進行繪制。我們所提供的圖片具有四個狀態(順序):正常態、下壓態、禁止態、懸停態,對應按鈕的四個狀態。

    (2)有了圖片按鈕類,我們需要將按鈕的資源加載進來。可以用CDXUTDialog::SetTexture實現。
    (3)四次調用CDXUTDialog::SetDefaultElement,為圖片按鈕設置四個元素。
    (4)分配CDXUTImageButton對象,調用CDXUTDialog::AddControl,然后設置該按鈕的ID、TEXT、位置、大小等元素。
    (2)、(3)、(4)步的示例代碼:
    //init custom button, normal way
    int iTexture = g_SampleUI.SetTexture(IDC_BUTTON_CUSTOM_1, L"play.tga");
    CDXUTElement elem;
    elem.iTexture = IDC_BUTTON_CUSTOM_1;
    elem.iFont = 0;
    RECT rc = {0};
    for(int i=0; i<4; i++)
    {
        SetRect(&rc, i*64, 0, (i+1)*64, 28);
        elem.SetTexture(IDC_BUTTON_CUSTOM_1, &rc, D3DCOLOR_ARGB(128, 255, 255, 255));
        g_SampleUI.SetDefaultElement(DXUT_CONTROL_SCROLLBAR+1, i, &elem);
    }
    CDXUTImageButton *imgbtn = new CDXUTImageButton(&g_SampleUI);
    g_SampleUI.AddControl(imgbtn);
    imgbtn->SetID(IDC_BUTTON_CUSTOM_1);
    imgbtn->SetText(L"CustomStyle");
    imgbtn->SetSize(64, 27);
    imgbtn->SetLocation(5, 5);

   
    如果改動DXUTGUI的源碼,則可以在枚舉類型DXUT_CONTROL_TYPE中添加DXUT_CONTROL_IMAGEBUTTON項,同時將上面的for循環設置默認元素集部分加入到InitDefaultElements函數中,給CDXUTDialog添加AddImageButton函數。那么生成按鈕的代碼看起來會相對簡潔一些,它可能是這個樣子:

g_SampleUI.AddImageButton(IDC_BUTTON_CUSTOM_1, L"CustomStyle", 5, 5, 64, 27);

    好了,DXUTGUI控件定制到此為止。

posted on 2008-05-18 15:53 lovedday 閱讀(2888) 評論(3)  編輯 收藏 引用 所屬分類: ■ DXUT Research

評論

# re: 【ZT】DXUTGUI控件的定制 2008-06-19 14:08 fly

你好,看了你的這篇文章,覺得很好,但是照搬你的代碼,編譯老是有錯誤,我還是個初學者,能將你的源程序發給我一份馬,不勝感激,謝謝!!!我的郵箱:taxueliuyun@sina.com  回復  更多評論   

# re: 【ZT】DXUTGUI控件的定制[未登錄] 2009-08-06 15:03 nancy

@fly
有沒有寫好的例子參考一下啊,我的郵箱957712059@qq.com  回復  更多評論   

公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            午夜精品福利一区二区三区av| 欧美一区二区国产| 欧美揉bbbbb揉bbbbb| 久久久一区二区| 欧美在线观看你懂的| 欧美中文字幕在线播放| 久久久久www| 久久综合狠狠| 欧美激情亚洲| 欧美日韩在线第一页| 欧美午夜精品久久久久久孕妇| 国产精品www网站| 国产亚洲一区二区三区在线播放| 狠狠色综合色区| 亚洲区一区二区三区| 在线视频免费在线观看一区二区| 香港久久久电影| 欧美成人午夜激情视频| 亚洲精品国产精品国自产观看| 亚洲人成在线观看| 性xx色xx综合久久久xx| 久久免费偷拍视频| 欧美日韩日韩| 国产香蕉97碰碰久久人人| 亚洲欧美在线免费观看| 亚洲午夜免费视频| 久久久久国内| 亚洲精品乱码久久久久久日本蜜臀 | 亚洲精品黄色| 亚洲一区自拍| 免费久久精品视频| 国产精品国产三级国产专播精品人 | 欧美视频中文字幕在线| 韩日精品在线| 一区二区三区国产精品| 久久亚洲一区二区三区四区| 9久re热视频在线精品| 久久国产精品免费一区| 欧美日韩性视频在线| 国内成人精品视频| 亚洲综合欧美| 亚洲免费精彩视频| 欧美11—12娇小xxxx| 国产视频观看一区| 亚洲——在线| 亚洲精品国产品国语在线app| 欧美伊人久久久久久久久影院 | 狠狠综合久久| 香蕉久久夜色精品国产使用方法| 亚洲国产精品黑人久久久| 香蕉久久一区二区不卡无毒影院 | 亚洲精品在线视频| 久久综合一区二区| 欧美亚洲三区| 国产视频丨精品|在线观看| 亚洲一区在线免费| 99精品国产在热久久下载| 欧美大秀在线观看| 亚洲精品日韩一| 亚洲国产精品成人| 欧美成人69| 亚洲精品国产日韩| 亚洲国产片色| 欧美人与禽猛交乱配| 一本色道久久加勒比88综合| 亚洲狠狠丁香婷婷综合久久久| 美女成人午夜| 亚洲欧洲三级| 亚洲精品看片| 欧美三级日本三级少妇99| 欧美区在线播放| 一区二区黄色| 一区二区三区四区国产| 国产精品ⅴa在线观看h| 亚洲欧美日本在线| 午夜久久美女| 激情视频一区二区| 欧美黄色影院| 欧美激情影院| 亚洲自拍偷拍福利| 午夜精品99久久免费| 国产一区二区三区视频在线观看| 久久久久综合一区二区三区| 久久精品视频免费| 亚洲精品欧美日韩专区| 99国产精品久久久久久久| 国产精品v日韩精品| 久久av老司机精品网站导航| 久久精品日韩欧美| 99国内精品久久久久久久软件| 日韩天堂在线观看| 国产亚洲一区精品| 亚洲欧洲一区二区三区在线观看| 国产精品成av人在线视午夜片| 欧美在线视频免费| 欧美激情国产日韩| 欧美一区二区三区四区在线观看地址| 欧美一区二区日韩| 亚洲精品一级| 欧美一区二区三区精品电影| 亚洲国产一区二区三区在线播| 亚洲三级视频在线观看| 国产综合色精品一区二区三区| 亚洲国产精品va在线观看黑人| 国产精品久久久久久久久搜平片| 久久综合久久综合九色| 欧美色精品在线视频| 久久野战av| 国产精品乱人伦一区二区| 欧美激情va永久在线播放| 国产精品一区三区| 亚洲精品国产精品国自产观看浪潮| 国产亚洲精品久久久久婷婷瑜伽| 亚洲国产国产亚洲一二三| 国产亚洲毛片| 亚洲私人影院在线观看| 亚洲另类在线视频| 久久久亚洲国产天美传媒修理工| 亚洲综合视频网| 欧美激情亚洲国产| 欧美成人精品一区二区| 国产麻豆成人精品| 夜夜嗨av色一区二区不卡| 亚洲国产精品一区二区尤物区 | 蜜桃伊人久久| 久久精品国产99国产精品澳门| 欧美日韩一区二区三区视频| 欧美国产日韩视频| 在线精品亚洲一区二区| 欧美一区二区性| 欧美一区二区黄色| 国产精品久久久| 一本在线高清不卡dvd| 99国产精品视频免费观看| 欧美一区二区三区四区视频| 日韩图片一区| 国产精品色在线| 亚洲国产另类 国产精品国产免费| 欧美日韩一区三区| 亚洲国产裸拍裸体视频在线观看乱了中文| 国产精品婷婷| 夜色激情一区二区| 亚洲视频自拍偷拍| 欧美成人有码| 欧美大片一区二区三区| 亚洲二区在线| 久久久久久97三级| 欧美成年人网| 亚洲国产精品一区| 麻豆成人精品| 亚洲国产婷婷综合在线精品| 亚洲国产高清自拍| 欧美黄色一区| av成人动漫| 欧美一区成人| 国产一区二区三区免费观看| 久久精品国产久精国产一老狼| 久久一区欧美| 亚洲国产视频直播| 欧美精品自拍偷拍动漫精品| 日韩亚洲精品电影| 性娇小13――14欧美| 国产视频一区在线观看一区免费| 性伦欧美刺激片在线观看| 另类尿喷潮videofree| 亚洲国产综合在线看不卡| 欧美激情导航| 在线亚洲自拍| 久久久在线视频| 91久久精品美女高潮| 欧美日韩在线综合| 欧美一级视频精品观看| 欧美18av| 亚洲一区二区不卡免费| 国产亚洲午夜| 欧美乱在线观看| 午夜视黄欧洲亚洲| 亚洲高清免费| 欧美一区二区三区四区夜夜大片| 伊人精品久久久久7777| 欧美日韩亚洲一区在线观看| 亚洲欧美一区二区视频| 欧美激情一区在线观看| 午夜精品视频一区| 亚洲经典自拍| 国产精品一区二区女厕厕| 免费不卡亚洲欧美| 亚洲网站在线看| 亚洲高清资源| 久久婷婷国产麻豆91天堂| 亚洲一区二区三区四区五区午夜 | 久久国产天堂福利天堂| 亚洲国产精品一区二区三区| 国产精品女人网站| 免费观看在线综合色| 欧美一区二区视频网站| 欧美精品日韩综合在线| 国产精品一卡二卡| 欧美成人精品高清在线播放| 欧美亚洲在线|