• <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>

            天行健 君子當(dāng)自強(qiáng)而不息

            【ZT】DXUTGUI控件的定制


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


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

                定制包含兩個(gè)方面,整個(gè)控件庫(kù)風(fēng)格的定制和特定控件實(shí)例本身的定制。

                我們先說(shuō)整個(gè)UI風(fēng)格的定制。

                我是從SDK的CUSTOMUI入手學(xué)習(xí)DXUT的。

                這個(gè)例子聲明了一個(gè)全局的對(duì)話框資源管理對(duì)象CDXUTDialogResourceManager g_DialogResourceManager,然后用它分別初始化三個(gè)對(duì)話框。以SampleUI對(duì)話框?yàn)槔跏蓟Z(yǔ)句在InitApp函數(shù)中: g_SamleUI.Init(&g_DialogResourceManager)。對(duì)Init函數(shù)的調(diào)用只有一個(gè)參數(shù),另一個(gè)是默認(rèn)的 bRegisterDialog=true。

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

                從Init函數(shù)入手來(lái)研究DXUTGUI的資源管理是個(gè)不錯(cuò)的選擇。我一路跟進(jìn)去,發(fā)現(xiàn)按照示例程序那樣初始化對(duì)話框時(shí),會(huì)從內(nèi)存中加載“皮膚”紋理。 DXUTGUI所用的內(nèi)存紋理資源是DDS格式的,保存在DXUTRes.cpp的g_DXUTGUITextureSrcData數(shù)組內(nèi)。這就是它的奧秘所在了。

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

                有了這個(gè)發(fā)現(xiàn),我們就可以實(shí)現(xiàn)自己的風(fēng)格了。只需兩步:

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

                需要注意的是,我們所做的圖片必須與DXUTGUI使用的圖片規(guī)格一樣,包括各種元素所對(duì)應(yīng)的紋理區(qū)域等等,否則可能會(huì)一團(tuán)糟。當(dāng)然還有一個(gè)辦法可以不和 DXUTGUI的圖片規(guī)格保持一致:修改CDXUTDialog::InitDefaultElements函數(shù)。

                研究InitDefaultElements函數(shù)可以了解DXUTGUI是怎么使用紋理皮膚的,有助于我們實(shí)現(xiàn)自己的皮膚。

            DXUTGUI提供的默認(rèn)控件已經(jīng)實(shí)現(xiàn)了透明效果和類(lèi)似色彩鍵的效果。在D3D中沒(méi)有直接的色彩鍵(direct draw中有)功能,不過(guò)可以利用alpha通道實(shí)現(xiàn)類(lèi)似的效果,只是需要圖片具有alpha通道。

                DXUTGUI的控件紋理正是這樣實(shí)現(xiàn)的,用photoshop打開(kāi)保存下來(lái)的紋理圖片,可以看到其alpha通道的圖片。

                要在D3D9中實(shí)現(xiàn)透明和顏色過(guò)濾功能,需要兩個(gè)步驟。

                (1)定義FVF結(jié)構(gòu)體,包含頂點(diǎn)顏色域。定義FVF標(biāo)記,使其包含D3DFVF_DIFFUSE。

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

                #define CUSTOMFVF   D3DFVF_XYZRHW | D3DFVF_DIFFUSE


                (2)設(shè)置渲染狀態(tài):

                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 );


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

                對(duì)應(yīng)在DXUTGUI中,如果要設(shè)置某一個(gè)控件的透明度,可以調(diào)用該控件的GetElement函數(shù),獲取CDXUTElement類(lèi)型的指針,調(diào)用其SetTexture函數(shù)實(shí)現(xiàn)。

                要統(tǒng)一設(shè)置某一類(lèi)控件的透明度,可以調(diào)用CDXUTDialog::GetDefaultElement獲取該類(lèi)控件的分子對(duì)象的指針,修改其TextureColor成員的alpha通道(或者調(diào)用SetTexture函數(shù))。

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


            定制控件

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

                研究CDXUTDialog的InitDefaultElements函數(shù)可以發(fā)現(xiàn),DXUTGUI為每種控件定義了若干元素,這些元素保存在 m_DefaultElements數(shù)組中。當(dāng)增加一個(gè)新的控件時(shí),比較控件類(lèi)型,將該類(lèi)型的元素集從DefaultElements取出,傳遞給該控件,該控件生成自己的元素實(shí)例并保存起來(lái)。

                我們發(fā)現(xiàn)紋理資源保存在CDXUTDialogResourceManager的成員變量m_TextureCache中。m_TextureCache 是一個(gè)動(dòng)態(tài)數(shù)組,可以保存任意的紋理資源,如一個(gè)按鈕的圖片紋理,一個(gè)列表框的背景紋理等。只需要調(diào)用CDXUTDialg::SetTexture函數(shù),指定一個(gè)ID和紋理文件名即可。

                紋理有了保存的地方,接下來(lái)只需要讓控件使用我們自己的紋理就可以進(jìn)行定制了。而控件的定制分為三類(lèi):?jiǎn)蝹€(gè)控件的定制、一類(lèi)控件的定制、生成新控件類(lèi)型。下面一一說(shuō)明怎么來(lái)實(shí)現(xiàn)。
             

                一、單個(gè)控件定制

                單個(gè)控件的定制比較簡(jiǎn)單,以按鈕為例,需要三步:

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

                上面的定制受限于DXUTGUI,需要根據(jù)其所實(shí)現(xiàn)的控件的渲染方法來(lái)生成自己的紋理資源,還要查看InitDefaultElements來(lái)決定怎么調(diào)用CDXUTElement::SetTexture和CDXUTElement::SetFont。

             

                二、單類(lèi)控件的定制

                某一類(lèi)控件的定制需要更改該類(lèi)控件的默認(rèn)元素,這個(gè)可以通過(guò)CDXUTDialog::SetDefaultElement來(lái)實(shí)現(xiàn)。需要兩步完成:

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

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

             

                三、生成新控件類(lèi)型

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

                (1)實(shí)現(xiàn)控件類(lèi)
                (2)加載資源
                (3)為新類(lèi)型控件生成默認(rèn)元素集
                (4)生成控件實(shí)例,添加到對(duì)話框

                我們不改變DXUT自己的文件,一切都在我們自己的文件中實(shí)現(xiàn)。

                (1)DXUTGUI提供的控件不一定能滿足我們需要,有時(shí)候需要自己實(shí)現(xiàn)新的控件,如圖片按鈕。我們可以從CDXUTControl派生,也可以從某個(gè)特定的控件類(lèi)派生。下面我們以圖片按鈕的實(shí)現(xiàn)為例來(lái)說(shuō)明,先看代碼。
            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指定一個(gè)控件類(lèi)型,取DXUT_CONTROL_SCROLLBAR + 1。同時(shí)改寫(xiě)CDXUTButton的Render函數(shù),依據(jù)按鈕狀態(tài)取不同的紋理元素進(jìn)行繪制。我們所提供的圖片具有四個(gè)狀態(tài)(順序):正常態(tài)、下壓態(tài)、禁止態(tài)、懸停態(tài),對(duì)應(yīng)按鈕的四個(gè)狀態(tài)。

                (2)有了圖片按鈕類(lèi),我們需要將按鈕的資源加載進(jìn)來(lái)。可以用CDXUTDialog::SetTexture實(shí)現(xiàn)。
                (3)四次調(diào)用CDXUTDialog::SetDefaultElement,為圖片按鈕設(shè)置四個(gè)元素。
                (4)分配CDXUTImageButton對(duì)象,調(diào)用CDXUTDialog::AddControl,然后設(shè)置該按鈕的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);

               
                如果改動(dòng)DXUTGUI的源碼,則可以在枚舉類(lèi)型DXUT_CONTROL_TYPE中添加DXUT_CONTROL_IMAGEBUTTON項(xiàng),同時(shí)將上面的for循環(huán)設(shè)置默認(rèn)元素集部分加入到InitDefaultElements函數(shù)中,給CDXUTDialog添加AddImageButton函數(shù)。那么生成按鈕的代碼看起來(lái)會(huì)相對(duì)簡(jiǎn)潔一些,它可能是這個(gè)樣子:

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

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

            posted on 2008-05-18 15:53 lovedday 閱讀(2858) 評(píng)論(3)  編輯 收藏 引用 所屬分類(lèi): ■ DXUT Research

            評(píng)論

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

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

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

            @fly
            有沒(méi)有寫(xiě)好的例子參考一下啊,我的郵箱957712059@qq.com  回復(fù)  更多評(píng)論   

            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(lèi)(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            伊人久久大香线蕉综合网站| 欧美丰满熟妇BBB久久久| 无码精品久久久天天影视| 久久国产福利免费| 久久精品国产免费一区| 久久久久久久人妻无码中文字幕爆| 综合久久一区二区三区 | 热99RE久久精品这里都是精品免费 | 偷偷做久久久久网站| 久久综合偷偷噜噜噜色| 四虎国产精品成人免费久久| 久久久久久久精品成人热色戒| 久久久久久曰本AV免费免费| 亚洲va久久久噜噜噜久久天堂| 日本人妻丰满熟妇久久久久久| 69久久夜色精品国产69| 久久精品国产一区二区三区不卡| 久久综合九色欧美综合狠狠| 精品国产乱码久久久久久呢| 亚洲精品乱码久久久久久蜜桃图片 | 色婷婷久久综合中文久久蜜桃av | 国产国产成人久久精品| 久久精品中文字幕有码| 一本色道久久HEZYO无码| 久久久久久九九99精品| 久久福利片| 亚洲va中文字幕无码久久不卡| 狠狠色丁香婷婷久久综合不卡| 久久久久亚洲AV成人网人人网站 | 久久99国产亚洲高清观看首页| 久久久久亚洲AV成人网人人网站| 精品久久久中文字幕人妻| 久久99国产精品二区不卡| 久久亚洲精品无码aⅴ大香| 9191精品国产免费久久| 偷窥少妇久久久久久久久| 99久久婷婷国产一区二区| 久久人人爽人人爽人人片av高请| 久久精品国产黑森林| 狠狠色婷婷综合天天久久丁香 | 国产精品成人99久久久久 |